user1202888
user1202888

Reputation: 1043

Call schema method from within pre save hook and update property

I want to call a function from within my pre save hook that updates a property in the instance that is being saved/updated. I don't want to call save() again inside the schema method.

Also, below is just an example, but I have some shema methods that get quite long, and I don't want to include them within the pre save hook.

UserSchema.pre('save', function(next) {
  const user = this;
  ...
  if (user.isModified('something')) {
    user.checkSomething();
  }
  ...
  next();
});

UserSchema.method.checkSomething() = function() {
  const user = this;

  if(user.something > 5) {
    // Any way to update the below property without calling save() again?
    user.somethingElse = true;
  }
}

It just seems the change is not being made permanent, once the function returns.

Thank you.

Upvotes: 1

Views: 1096

Answers (1)

Jason Cust
Jason Cust

Reputation: 10919

Aside from typos in your example code, my only guess is the checkSomething function has an async operation and the pre-save middleware is running synchronously.

// include `done` for async operation
UserSchema.pre('save', function(next, done) {
  const user = this;

  next();

  if (user.isModified('something')) {
    // Assuming this is asynchronous
    user.checkSomething(done);
  } else {
    done();
  }
});

UserSchema.method('checkSomething', checkSomething);

// Async function
function checkSomething(cb) {
  const user = this;

  if (user.something > 5) {
    doSomethingAsync(function(err, res) {
      if (err) {
        return cb(err);
      }

      user.somethingElse = res;
      cb();
    });
  } else {
    cb();
  }
}

NOTE: If you are modifying instance values I would recommend doing so in the pre-validate step so the model can validate the modified values before saving.

UserSchema.pre('validate', function(next) {
  const user = this;

  if (user.isModified('something')) {
    // Assuming this is synchronous
    user.checkSomething();
  }

  next();
});

UserSchema.method('checkSomething', checkSomething);

function checkSomething() {
  const user = this;

  if (user.something > 5) {
    user.somethingElse = true;
  }
}

Upvotes: 1

Related Questions