Reputation: 1039
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
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
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