My code below doesn't allow the API user to update only one field by passing one request property. I can remove the null at userObj
, but the UI developer will have to pass existing data from the database to do an update, which is not the best practice.
Here is my Express route:
router.put('/user', (req, res) => {
const userObj = {
name: req.body.name || null,
location: {
city: req.body.city || null
},
phone: req.body.phone || null
};
User.updateUser(req.body.id, userObj)
});
Here is my Mongoose model's updateUser
function:
module.exports.updateUser = (_id, userObj, callback) => {
User.findOneAndUpdate({_id}, userObj, { upsert: true, 'new': true }, callback);
}
My code below doesn't allow the API user to update only one field by passing one request property. I can remove the null at userObj
, but the UI developer will have to pass existing data from the database to do an update, which is not the best practice.
Here is my Express route:
router.put('/user', (req, res) => {
const userObj = {
name: req.body.name || null,
location: {
city: req.body.city || null
},
phone: req.body.phone || null
};
User.updateUser(req.body.id, userObj)
});
Here is my Mongoose model's updateUser
function:
module.exports.updateUser = (_id, userObj, callback) => {
User.findOneAndUpdate({_id}, userObj, { upsert: true, 'new': true }, callback);
}
Share
Improve this question
edited Aug 7, 2017 at 5:19
Andrew Li
58k14 gold badges134 silver badges148 bronze badges
asked Aug 7, 2017 at 5:03
Jessie AndersonJessie Anderson
3196 silver badges13 bronze badges
2 Answers
Reset to default 16First, to address your issue with updating only a few certain properties, you have to use the $set
operator to set only a certain field. When you pass userObj
directly to findOneAndUpdate
you reset the whole object thus you have to pass all the existing properties. Use $set
:
User.findOneAndUpdate({_id}, { $set: userObj }, { upsert: true, new: true }, callback);
This will update only the properties defined in userObj
to their new values and touch nothing else. Also, you could just use findByIdAndUpdate
for this very use-case:
User.findByIdAndUpdate(_id, { $set: userObj }, { upsert: true, new: true }, callback);
Next, you shouldn't be using PUT. Use PATCH. PUT implies putting a resource at some URL, and replacing it entirely if it already exists. PATCH means you update only a few properties of a resource, and does replace the whole thing. This won't affect the app's functionality, but it's a huge semantics issue and end-user issue as they'd expect PATCH.
Use $set
User.findOneAndUpdate({_id}, {$set: userObj}, /* ... */)