Balkrishna Sawant
Balkrishna Sawant

Reputation: 21

Sequential execution of nodejs code with mongodb query

I am having situation where I need to fire a mongodb queries from nodejs(expressjs) code and pass the result of the query as a response to the request of my web api, but before my query executes the next lines of code gets execute and the blank response is sent back. The code that I have written is as follows,

router.get('/recent', function (req, res){
    var result = [];
    router.db.collection('Posts').find({},{ _id : 1, uid : 1, imagePath : 1, cntLikes : 1, uploadDate : 1}).limit(5).sort({ uploadDate : -1 }).toArray(function(err, docs) {
                docs.forEach( function (doc){
                        router.db.collection('Users').findOne({ "_id" : mongodb.ObjectId(doc.uid)}, function (err, user){
                            doc.username = user;
                            result.push(doc);
                            });
                });


    res.send(result);     // this line send empty result to caller
    });
});

I have tried callback methods, async.waterfall and programmatically stop the execution but everything failed. I have also tried promises but i dont think promises can help me in this scenario.

Upvotes: 0

Views: 844

Answers (2)

Subburaj
Subburaj

Reputation: 5192

Try for this:

router.get('/recent', function (req, res){
    var result = [];
    router.db.collection('Posts').find({},{ _id : 1, uid : 1, imagePath : 1, cntLikes : 1, uploadDate : 1}).limit(5).sort({ uploadDate : -1 }).toArray(function(err, docs) {
    var counter = 0;
                docs.forEach( function (doc, index){
                        counter++;
                        router.db.collection('Users').findOne({ "_id" : mongodb.ObjectId(doc.uid)}, function (err, user){
                            doc.username = user;
                            result.push(doc);
                            if(counter === index){
                             res.send(result);    
                            }
                            });
                });        
    });
});

Upvotes: 1

Jim Jeffries
Jim Jeffries

Reputation: 10081

You are using another asynchronous call within your loop, which is being executed after res.send(result). I think what you're after is async.map, so maybe something along the lines of this within your posts callback

function addUserToPost(item, callback) {
    router.db.collection('Users').findOne({ "_id" : mongodb.ObjectId(doc.uid)}, function (err, user){
        doc.username = user;
        callback(err, doc);
    });
}

async.map(docs, addUserToPost, function(err, posts) {
    res.send(posts);
});

You want to map from you 'Posts' to Posts with user information added.

Upvotes: 1

Related Questions