Reputation: 2854
I have following two collection:
1) Users: {name: xyz,
email:[email protected]}
2) Posts: {_id: 12345678,
time:asdfg,
authEmail:[email protected],
description: asdigligvilud}
Here i want to get the details of each post along with the corresponding name of author id. So i wrote query like this:
// get all the posts
Posts.find((err, posts)=> {
if (err) { next(err) };
var data = Array();
var count = 0;
var len = posts.length;
// function to check the end of inner queries
var checkloop = function(){
count++;
if(count===len)
return res.json({result:data,
msg:'success'});
}
for(var i=0;i<len;i++){
Users.findOne({email:posts[count].authEmail},(err,usr)=>{
if(usr){
var item = {
'authorName':usr.name?
'email':usr.email,
'postDesc':posts[count].desc,
'creationTime':posts[count].time
}
data.push(item);
}
checkloop();
});
}
});
But i am getting same result for each iterations that is the post deatils and author id corresponding to the very first loop that is posts[0] only. So i think its because of asynchronous nature of queries. Is there any standard way to make such query in mongodb or do i need to change my callback method?
Thanks in advance.
Upvotes: 0
Views: 235
Reputation: 1124
I believe the issue you had was because count
inside the for loop probably was meant to be i
. In addition, each loop iteration captures the same variable i
in the Users.findOne
callback, but the callback should be able to refer to the post that was queried. Without making much changes, I think this can work with using forEach
over the returned posts like below:
// get all the posts
Posts.find((err, posts)=> {
if (err) { next(err) };
var data = Array();
var count = 0;
var len = posts.length;
// function to check the end of inner queries
var checkloop = function(){
count++;
if(count===len)
return res.json({result:data,
msg:'success'});
}
posts.forEach((post) => {
Users.findOne({email:post.authEmail},(err,usr)=>{
if(usr){
var item = {
'authorName':usr.name?
'email':usr.email,
'postDesc':post.desc,
'creationTime':post.time
}
data.push(item);
}
checkloop();
}
});
});
Upvotes: 1