Reputation: 21
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
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
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