Poot87 Poot87 - 5 months ago 22
JSON Question

Why is my Mongoose query within a loop only returning the first result?

I have been struggling with this for days now. I am trying to return the data that is referenced by a list of IDs.

Example JSON of one team:

{
"Name":"Team 3",
"CaptainID":"57611e3431c360f822000003",
"CaptainName":"Name",
"DateCreated":"2016-06-20T10:14:36.873Z",
"Members":[
"57611e3431c360f822000003", //Same as CaptainID
"57611e3431c360f822000004" //Other members
]
}


Here is the route:

router.route('/teams/:user_id')
.get(function (req, res) {

TeamProfile.find({
Members : {
$in : [req.params.user_id]
}
}).exec(function (err, teamProfiles) {

teamProfiles.forEach(function (teamProfile) {

UserProfile.find({
UserID : {
$in : teamProfile.Members.map(function (id) {
return id;
})
}
}, function (err, userProfiles) {
teamProfile.Members = userProfiles;
console.log(teamProfile); //will console log the remaining 2
})
.exec(function (err) {
res.json(teamProfile) //returns the first one only
})
})
});
})


The idea is for the route to return the profiles just by using the IDs to fetch the up-to-date data.

However, it is working to a point. It gets the user information and all but it doesn't return all the Teams + all the users as commented in the code. There are 3 teams in total. Only the first one is returned. If I remove
res.json(teamProfile)
it console logs all 3 teams. I want to return all 3 teams.

Answer

This is because your response is being called before completing all db operations. So instead of for each use async.forEach function. Install async module

var  async = require('async');
router.route('/teams/:user_id').get(function (req, res) {

TeamProfile.find({
    Members : {
        $in : [req.params.user_id]
    }
}).exec(function (err, teamProfiles) {

    async.forEach(teamProfiles,function (teamProfile,cb) {

        UserProfile.find({
            UserID : {
                $in : teamProfile.Members.map(function (id) {
                    return id;
                })
            }
        }, function (err, userProfiles) {           
            teamProfile.Members = userProfiles;
            cb() // Callback
        })

    },function(){
       res.json(teamProfile) 
    })
});
})