Darth.Vader
Darth.Vader

Reputation: 6271

Render page in express after for loop completes

I have to run mongoose query repeatedly within a for loop and once that completes, I want to render a page in express. Sample code given below. Since mongoose runs asynchronously, how can I make the 'commands/new' page to render only once the 'commands' array has been populated within the for loop?

...
...
var commands = [];
for (var index=0; index<ids.length; index++) {
    mongoose.model('Command').find({_id : ids[index]}, function (err, command){
        // do some biz logic with the 'command' object
        // and add it to the 'commands' array
        commands[index] = command;
    });
}

res.render('commands/new', {
    commands : commands
});
...
...

Upvotes: 2

Views: 699

Answers (1)

Blakes Seven
Blakes Seven

Reputation: 50406

Your basic for loop here does not respect the callback completion of the asynchronous methods you are calling before executing each iteration. So simply use something that does instead. The node async library fits the bill here, and in fact for even better methods of array iteration:

var commands = [];

async.each(ids,function(id,callback) {
    mongoose.model("Command").findById(id,function(err,command) {
        if (command) 
            commands.push(command);
        callback(err);
    });
},function(err) {
   // code to run on completion or err
})

And therefore async.each or possibly a variant like async.eachLimit which will only run a limited number of parallel tasks as set will be your better loop iteration control methods here.

NB The .findById() method of Mongoose also helps shorten coding here.

Upvotes: 2

Related Questions