Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check modified fields in pre/post update hook in Mongoose.js

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.

like image 958
jemlifathi Avatar asked Oct 05 '17 15:10

jemlifathi


People also ask

What is .pre in mongoose?

Sponsor #native_company# — #native_desc# Middleware (also called pre and post hooks) are functions which are passed control during execution of asynchronous functions. Middleware is specified on the schema level and is useful for writing plugins.

What is $in in mongoose?

The value of the $in operator is an array that contains few values. The document will be matched where the value of the breed field matches any one of the values inside the array.

What is updateOne in mongoose?

Mongoose | updateOne() Function The updateOne() function is used to update the first document that matches the condition. This function is the same as update(), except it does not support the multi or overwrite options.

What are pre and post hooks?

Pre- and post-execution hooks are Processing scripts that run before and after actual data processing is performed. This can be used to automate tasks that should be performed whenever an algorithm is executed.


2 Answers

try it:

 schema.post('update', function () {
     const modifiedFields = this.getUpdate().$set;
     // ...
 });
like image 80
Sajjad Shirazy Avatar answered Sep 20 '22 07:09

Sajjad Shirazy


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 
});
like image 32
Piotr Kowalski Avatar answered Sep 23 '22 07:09

Piotr Kowalski