Mongoose custom validation of several fields on update Mongoose custom validation of several fields on update mongoose mongoose

Mongoose custom validation of several fields on update


Due to limitation of working with update() I've decided to solve the problem this way:

  • Use custom validators (idea #1 mentioned in the question)
  • Don't use update()

So instead of

User.update({ _id: id }, { $set: { avatar: 'user1.png' } });

I use

User.findOne({ _id: id })    .then((user) => {        user.avatar = 'user1.png';        user.save();    });

In this case custom validators work as expected.

P.S. I choose this answer as a correct one for me, but I will give bounty to the most relevant answer.


You can do this with the context option specified in the mongoose documentation.

The context option

The context option lets you set the value of this in update validators to the underlying query.


So in your code you can define your validator on the path like this:

function validateAvatar (value) {    // When running update validators with the `context` option set to    // 'query', `this` refers to the query object.    return this.getUpdate().$set.active;}schema.path('avatar').validate(validateAvatar, 'User is not active');

And while updating you need to enter two options runValidators and context. So your update query becomes:

var opts = { runValidators: true, context: 'query' };user.update({ _id: id }, { $set: { avatar: 'user1.png' }, opts });


Did you try giving active a default value so it would not be undefined in mongodb.

const schema = new mongoose.Schema({active: { type: Boolean, 'default': false },avatar: { type: String,          trim: true,          'default': '',          validate: [validateAvatar, 'User is not active']}});function validateAvatar (value) {    console.log(value); // user.avatar    console.log(this.active); // undefined}

When creating do you set the user in this way

  var User = mongoose.model('User');  var user_1 = new User({ active: false, avatar: ''});  user_1.save(function (err) {            if (err) {                return res.status(400).send({message: 'err'});            }                           res.json(user_1);                        });