How to check modified fields in pre/post update hook in Mongoose.js
Solution 1
If you want to know what fields you are modifying, then you need to issue an update command by calling save
:
Tank.findById(id, function (err, tank) {
if (err) return handleError(err);
tank.set({ size: 'large' });
tank.save(function (err, updatedTank) {
if (err) return handleError(err);
res.send(updatedTank);
});
});
This way pre-save hook will be invoked and you will be having access to:
Document.prototype.modifiedPaths()
because this
in pre-save hook refers to the document:
TankSchema.pre('save', function (next) {
// ...
this.modifiedPaths();
// ...
});
On the other hand, you will not be able to achieve the same result when issuing an update command by calling update
:
Tank.update({ _id: id }, { $set: { size: 'large' }}, callback);
because when calling update
, document hooks (e.g. pre-save, post-save) are not being executed at all. Instead, query hooks are being executed (e.g. pre-update, post-update) in that case. And the issue with query hooks is that this
inside of them does not reference the document, so this.modifiedPaths === undefined
schema.post('update', function (doc) {
// `this` refers to model.Query
// `doc` refers to CommandResult
});
Solution 2
try it:
schema.post('update', function () {
const modifiedFields = this.getUpdate().$set;
// ...
});
Solution 3
There is no direct way of doing it. There is a variable called isNew which is being tracked by mongoose to check if a new document is created.
see Document#isNew for information on Document#isNew
However, you can created your own tracker to check in post save hook to identify wether document is updated or not.
schema.pre('save', function (doc) {
this.isDocUpdated = false;
if (this.isModified()) {
this.isDocUpdated = true;
}
});
schema.post('save', function (doc) {
if (this.isDocUpdated) {
console.log('post save hook called');
}
});
Related videos on Youtube
jemlifathi
Updated on June 04, 2022Comments
-
jemlifathi almost 2 years
I need to know modified fields or if a specific field was modified in pre or post update hook in a Mongoose schema. I tried the following, but still unable to figure it out:
schema.post('update', function (doc) { //check modified fields or if the name field was modified and then update doc });
I know maybe there is a method isModified like in pre save but I don't know how to do the same with update hooks. Any suggestions will be appreciated.
-
jemlifathi over 6 yearsIt returns
TypeError: doc.modifiedPaths is not a function
There is no function named modifiedPaths in doc -
Twig2let over 6 yearsMy mistake. It appears
modifiedPaths
is not available in the post middleware. Have updated the answer. -
jemlifathi over 6 yearsI know there is such function in pre save hook, but as I mentioned in my question I need to check updated fields in pre/post update hook. comprende?
-
Up209d over 4 yearsThis is not an answer, whatever fields you throw in $set of update will be listed there, not matter what they are different or same with the old value.
-
omer over 4 yearsYou have a typo in the code. The second hook should be 'post' and not 'pre'
-
joniba over 3 yearsvery helpful answer!