How to check modified fields in pre/post update hook in Mongoose.js
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 });
try it:
schema.post('update', function () { const modifiedFields = this.getUpdate().$set; // ... });
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'); }});