Wednesday, 15 March 2017

Fixing asynchronous issues without callback? [duplicate]

This question already has an answer here:

I'm working on a small personal project to learn Node.js and I've been having an issue I believe is caused due to the fact that Node is asynchronous, but I have no idea how to fix it. I've created a RESTful API where users can create "rooms", add food categories (categories) to rooms, and receive food recommendations from Yelp. I hope to update the recommendations (options) each time the category is updated. However, every time a category is added, no options are added to the room. Can anyone take a look at this?

// Updates details of specific room with name `room_id`
.put(function(req, res) {

    Room.findOne({name: req.params.room_id}, function(err, room) {
        if (!err) {
            var response = {errors: []};
            if (req.body.action == 'category') {

                // =========================================================
                // Add category to room or increase category weight
                // =========================================================

                // Clear current options
                room.options = [];

                // Add categories to room
                var categories = req.body.category;
                var currentCategories = room.categories.map(c => c.name)

                if (typeof categories == "string") {
                    categories = [categories];
                }

                // Validate new categories
                for (index = 0; index < categories.length; index++) {
                    var category = categories[index].toLowerCase();
                    // Confirm category on Yelp
                    if (acceptableCategories.indexOf(category) == -1) {
                        response.errors.push(category + " is not an acceptable category");
                        continue;
                    }
                    // Add category or add vote for category
                    var categoryAlreadyUsed = (currentCategories.indexOf(category) > -1)
                    if (categoryAlreadyUsed) {
                        var categoryIndex = currentCategories.indexOf(category);
                        room.categories[categoryIndex].votes += 1;
                    } else {
                        room.categories.push({name: category, votes: 1});
                    }
                }

                // =========================================================
                // Add options to room based on category weights
                // =========================================================

                // Reload options based on categories
                var totalVotes = room.categories.reduce((a, b) => a += b.votes, 0);

                // Create array of Yelp categories and items needed
                var categoriesAndItems = room.categories.map(function(category) {
                    var title = yelpCategories.filter(x => x.title.toLowerCase() == category.name.toLowerCase())[0].alias; // forgive me
                    var votes = Math.round((category.votes / totalVotes) * 10);
                    return {name: title, items: votes};
                });

                // Commence Yelp searches
                for (var index = 0; index < categoriesAndItems.length; index++) {
                    // Search for each category as weighted by it's votes
                    yelp.search({
                        category_filter:categoriesAndItems[index].name,
                        cll:room.location.latitude + ',' + room.location.longitude,
                        location:"Austin, TX",
                        limit:categoriesAndItems[index].items,
                    }).then(function(data) {
                        // Add results for each search to options
                        var businesses = JSON.parse(JSON.stringify(data)).businesses;
                        for (var result = 0; result < businesses; result++) {
                            var option = businesses[result];
                            room.options.push({name: option.name, url: option.mobile_url, votes: 0});
                        }
                        console.log(businesses.map(x => x.name));
                        console.log(room.options.map(x => x.name));
                    }).catch(function(err) {
                        response.errors.push(err);
                    });
                };
            }


            if (response.errors.length != 0) {
                res.json(response);
            } else {
                room.save(function(err) {
                    if (!err) {
                        res.json(room);
                    } else {
                        res.send(err);
                    }
                })
            }
        } else {
            res.send(err);
        }
    });
})



via Ian Mobbs

No comments:

Post a Comment