Reputation: 1649
For my Edit user route, I will need to handle a number of different possible circumstances. A user could update their profile and only change their email address or password, but they might update a whole range of other profile information at once too.
The advantage of findOneAndUpdate
is that you can pass the update object and it will only change those fields from the request that are different than the saved data. This is great! One HUGE problem -- this query bypasses validators and middleware for some reason (even with runValidators=true
, it bypasses pre-save hooks, meaning password updates bypass being encrypted).
So the solution I keep seeing everywhere is to do a findOne
or findById
, update fields manually, and then run user.save()
.
However, with a fairly complicated user record, that means my route would look something like this and would be very hard to maintain:
exports.editUser = async function(req, res, next) {
try {
const id = req.params.id;
let user = await db.User.findById(id);
user.email = req.body.email;
user.fullName = req.body.fullName;
user.password = req.body.password;
user.otherField = req.body.otherField;
user.otherField = req.body.otherField;
user.otherField = req.body.otherField;
user.otherField = req.body.otherField;
user.otherField = req.body.otherField;
user.otherField = req.body.otherField;
user.otherField = req.body.otherField;
user.otherField = req.body.otherField;
user.otherField = req.body.otherField;
user.otherField = req.body.otherField;
user.otherField = req.body.otherField;
let updatedUser = await user.save();
return res.status('200').json(user);
}
Is there any way to mimic the behavior of passing the updates object to Mongoose where I can just give it req.body
and let it only update the fields that are different?
Upvotes: 0
Views: 26
Reputation: 953
https://lodash.com/docs/4.17.11#merge
_.merge(user, req.body)
This will merge **EVERYTHING **. Use only if you don't care about security.
To limit to certain fields without going crazy:
const { f1, f2, f3 } = req.body;
_.merge(user, { f1, f2, f3})
Or refer to this: https://lodash.com/docs/4.17.11#pick
Slightly non-obvious feature in lodash.
_.merge(user, _.pick(req.body, ['f1', 'f2', 'f3']))
Upvotes: 1