Node.js - Mongoose - Update nested array with all values in req.body
Solution 1
You would need to use the $
positional operator in your $set
. In order to assign those properties dynamically, based on what is in your req.body
, you would need to build up your $set
programmatically.
If you want to update the name you would do the following:
Location.update(
{ 'competitors._id': req.params.competitorId },
{ $set: { 'competitors.$.name': req.body.name }},
(err, result) => {
if (err) {
res.status(500)
.json({ error: 'Unable to update competitor.', });
} else {
res.status(200)
.json(result);
}
}
);
One way you might programatically build up the $set
using req.body
is by doing the following:
let updateObj = {$set: {}};
for(var param in req.body) {
updateObj.$set['competitors.$.'+param] = req.body[param];
}
See this answer for more details.
Solution 2
To update embedded document with $ operator, in most of the cases, you have to use dot notation on the $ operator.
Location.update(
{ _id: '577fe7a842c9b447', 'competitors._id': req.params.competitorId, },
{ $set: { 'competitors.$.name': req.body.name, }, },
(err, result) => {
if (err) {
res.status(500)
.json({ error: 'Unable to update competitor.', });
} else {
res.status(200)
.json(result);
}
}
);
Jacob
Updated on June 07, 2022Comments
-
Jacob almost 2 years
I have an object that looks like this.
{ _id: '577fe7a842c9b447', name: 'Jacob\'s Bronze Badges', competitors: [ { _id: '577fe7a842c9bd6d', name: 'Peter\'s Silver Badges', sites: [ { _id: '577fe7a842c9bd6d', name: 'Facebook', url: 'fb.com/peter' }, { _id: '577fe7a842c9bd6d' name: 'Google', url: 'google.com/peter' } ] }, { _id: '599fe7a842c9bd6d', name: 'Paul\'s Gold Badges', sites: [ { '_id': '577fe7a842c9bd6d', name: 'Facebook', url: 'fb.com/paul' }, { _id: '577fe7a842c9bd6d', name: 'Google', url: 'google.com/paul' } ] } ] }
My goal is to reference the
competitors
array and update items inside with all of the values fromreq.body
. I based this code off of this answer, as well as this other one.Location.update( { 'competitors._id': req.params.competitorId, }, { $set: { 'competitors.$': req.body, }, }, (err, result) => { if (err) { res.status(500) .json({ error: 'Unable to update competitor.', }); } else { res.status(200) .json(result); } } );
I send my
HTTP PUT
tolocalhost:3000/competitors/577fe7a842c9bd6d
to update Peter's Silver Badges. The request body is:{ "name": "McDonald's" }
The problem is that when I use
$set
to set the competitor with_id: req.params.competitorId
, I don't know what is inreq.body
. I want to use the entirereq.body
to update the object in the array, but when I do, that object is overwritten, so instead of getting a new name, Peter's Silver Badges becomes:{ name: 'McDonald\'s', sites: [] }
How can I update an object within an array when I know the object's
_id
with all of the fields fromreq.body
without removing fields that I want to keep?I believe that the
sites
array is empty because the object was reinitialized. In my schema I havesites: [sitesSchema]
to initialize it. So I am assuming that the wholecompetitors[_id]
object is getting overwritten with the new name and then thesites: [sitesSchema]
from myschema. -
meenachinmay about 4 yearsyes it is working but in my code i have to send two request for a query to exexute it. ```