Normand Julian Normand Julian - 1 month ago 20
Node.js Question

Multiple mongoose call with async

i'm new with node and mongoose.
I do multiple queries to find my datas so I use async to populate an array and then send it back the the client.

I try to get all the stats from the games I found.

Here is my Schema : [Team] 1 ---> N [Game] 1 ---> N [Stat]

var json = []; // The variable I will send back

async.waterfall([
function( team, next ) { // Find all games from a team (with its id)
dbGame.find({ team_id: req.params._id }).exec( next );
},
function( games, next ) {
for (key in games) { // For all games, finds their stats
dbStat.find({ game_id: games[key]._id }).exec(function(err, stats) {
json.push({
_id : games[key]._id,
stats : stats
}); // The json I need to return
});
if ( Number(key) === Number(games.length -1) ) {
next(json);
}
}
}
], function () {
res.status(200);
res.json(json);
});


The variable json send is always empty because of the asynchronous and I don't know how to have the full one.




update #1

Ok it's cool it's working.

But just a trouble, all the stats are in all json in the object :

Juste a problem : The stats from all games are stored in all json.

[{
_id:"57cb15f73945ac9808fe5422",
stats:Array[13]
}, {
_id:"57ff76fd78ca91a17b25dd1b",
stats :Array[13]
}]


But I think i can sort then. Here's my code now :

async.waterfall([
function(next) { // Find all games from a team (with its id)
dbGame.find({
team_id: req.params._id
}).sort({
_id: 1
}).exec(next);
},
function(games, next) {
var gameIds = games.map(function(game) {
return game._id;
});
dbStat.find({
game_id: {
$in: gameIds
}
}).sort({game_id: 1}).exec(function(err, stats) {
json = gameIds.map(function (id) {
return {
_id: id,
stats: stats
}
});
next(err, json);
});
}
], function(err, json) {
jsonResponse(res, 200, json);
});

Answer

You are not passing the results of the first find to the next step of waterfall, and when you call next(json); you are passing json as error, as the first argument is an error. Try:

async.waterfall([
    function(team, next) { // Find all games from a team (with its id)
        dbGame.find({
            team_id: req.params._id
        }).sort({
            _id: 1
        }).exec(next(err, games));
    },
    function(games, next) {
        var gameIds = games.map(function(game) {
            return game._id;
        });

        dbStat.find({
            game_id: {
                $in: gameIds
            }
        }).sort({game_id: 1}).exec(function(err, stats) {
          json = gameIds.map(function (id) {
            return {
              _id: id,
              stats: stats
            }
          });
          next(err, json);
        });
    }
], function(err, json) {
    res.status(200);
    res.json(json);
});