quantum
quantum

Reputation: 1420

Updating each element in MongoDB database in for loop

I have an array of userIDs (MongoDB Objectids)which I want to iterate through and for each one, find its user entry in my MongoDB database of users, and update it, say modify the user's age. Then only when every user has been updated, do I want to say res.send(200); in my Node.js Express app.

I started out with the following code which is just plain wrong because of the asynchronous calls to findById:

for (var i = 0; i < userIDs.length; i++) {
    var userID = userIDs[i];

    User.findById(userID, function (err, user) {
        if (err) throw err;

        // Update user object here

        user.save(function (err, user) {
            if (err) throw err;
            res.send(200);
        });
    });
}

Any ideas how I can do this? Is there perhaps a synchronous version of findById? Or perhaps a way to map through the array and apply a function to each element?

Thanks!

Upvotes: 0

Views: 104

Answers (2)

Ilan Frumer
Ilan Frumer

Reputation: 32367

The best way is to use promises.

An example with Q#all:

var q = require('Q');

var promises = userIDs.map(function(userID){

  var deferred = q.defer();

  User.findById(userID, function (err, user) {
     if (err) return deferred.reject(err);

    // Update user object here

    user.save(function (err, user) {
      if (err) return deferred.reject(err);      
      deferred.resolve(user);
    });
  });

  return deferred.promise;

});


q.all(promises)
  .then(function(users){
    res.json(users);
  })
  .fail(function(err){
    res.send(500,err);
  });

Upvotes: 2

autodidact
autodidact

Reputation: 256

I think you want the forEach method of npm's async module. It would look something like this:

async.forEach(userIDs, function(id, callback) {
    User.findById(id, function(err, user){
        if(err) throw err;
        user.save(function(err, user){
            if(err) throw err;
            callback();
        }
    }, function(err){
        if(err){
            throw err;
        } else {
            res.send(200);
        }
    }
}

Upvotes: 2

Related Questions