jj-aa
jj-aa

Reputation: 1039

update multiple documents with mongodb

How to iterate an array of objects to update documents with mongodb and keep the modified documents to return back in the response

Notice the comments in the code

.put(function (req, res) {

    var data = req.body.data;
    var documents = [];
    for (var item in data) {

        var id = data[item]._id;
        var document = data[item];

        Item.update({ _id: id }, document, { overwrite: true }, function (err, item) {
          if (err) {
            res.send({'error':'Error'});
          }
          Item.findById(id, function (err, document) {
            if (err) {
              res.send({});
            }
            documents.push(document); // documents are pushed
          });

        });        
    }
    documents ; // value is []
    res.json({
      items: documents
    });        
}) 

Upvotes: 2

Views: 1057

Answers (2)

Blakes Seven
Blakes Seven

Reputation: 50406

Use Promise.all() and .findByIdAndUpdate() instead. As long as your enviroment supports the ES6 contructs, or you import something that provides the Promise.all():

Promise.all(
    req.body.data.map(function(doc) {
        var id = doc._id;
        delete doc._id;
        return Item.findByIdAndUpdate(id,doc,{ "new": true });
    })
).then(function(documents) {
    res.json({ "items": documents })
});

No need for external libraries.

Upvotes: 2

hyades
hyades

Reputation: 3170

Since update is async, your documents is empty and return immediately. Create promises for each of the update. Also create a outer promise array. Push these promises to this array, and send the response when all are done. I am using the Q library

.put(function (req, res) {

    var data = req.body.data;
    var documents = [];
    var promises = []
    for (var item in data) {

        var id = data[item]._id;
        var document = data[item];
        var itemDefer = Q.defer();

        Item.update({ _id: id }, document, { overwrite: true }, function (err, item) {
          if (err) {
            res.send({'error':'Error'});
          }
          Item.findById(id, function (err, document) {
            if (err) {
              itemDefer.reject(err);
            }
            itemDefer.resolve(document);
          });
        });  
        promises.push(itemDefer.promise);      
    }
    Q.all(promises).then(function(documents) {
        res.json({items: documents});    
    }, then(function(err) {
        res.send({})
    }))

}) 

Upvotes: 1

Related Questions