Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mongoose difference between pre save and validate? When to use which one?

Currently I am using pre('save') to do validation:

UserSchema.pre('save', true, function(next, done) {
    var self = this //in case inside a callback
    var msg = helper.validation.user.username(self.username)
    if (msg) {
        self.invalidate('username', msg)
        done(helper.getValidationError(msg))
    }
    else
        done()
    next()
})

The helper module has a function that accepts an input and returns error message.

exports.user = {
    username: function(input) {
        if (!input)
            return 'username is required'
        var min = 3
        var max = 10
        if (input.length < min)
            return 'username min of length is ' + min
        if (input.length > max)
            return 'username max of length is ' + max
        return null
    }
}

There is another api validate to do similar things. What's the difference between them and which one should I use in what cases?

like image 350
OMGPOP Avatar asked Jul 17 '15 08:07

OMGPOP


People also ask

What is the need of Mongoose .how it is useful for validation?

Mongoose gives us a set of useful built-in validation rules such: Required validator checks if a property is not empty. Numbers have min and max validators. Strings have enum , match , minlength , and maxlength validators.

What is pre save in mongoose?

The save() function triggers validate() hooks, because mongoose has a built-in pre('save') hook that calls validate() . This means that all pre('validate') and post('validate') hooks get called before any pre('save') hooks.

What is validation in mongoose?

Validation is defined in the SchemaType. Validation is middleware. Mongoose registers validation as a pre('save') hook on every schema by default. You can disable automatic validation before save by setting the validateBeforeSave option. You can manually run validation using doc.

What does Mongoose unique validator do?

mongoose-unique-validator is a plugin which adds pre-save validation for unique fields within a Mongoose schema. This makes error handling much easier, since you will get a Mongoose validation error when you attempt to violate a unique constraint, rather than an E11000 error from MongoDB.


2 Answers

Update:

The validation is performed before the user defined hooks. You can follow this github post, where the contributor states,

not implementing this. validating first gives us a chance to stop before continuing into user defined hooks which may include async updates to other collections.

if we need validation to run again after we make a change from inside a hook we can always manually run this.validate(next).


Outdated:

Yeah, there is a small difference i know.

Pre hooks are executed before validations.

There is a closed issue on github asking for validation before pre hooks, https://github.com/Automattic/mongoose/issues/400.


And also there is a reason for not having validation before pre hooks, stated in the same link by @kamholz:

Say you have two fields, foo and fooSort, both are required. fooSort is a lowercased or otherwise transformed version of foo to be used in sorting. Since fooSort can be automatically generated, it makes sense to do so in a pre-save hook. But since validation runs first, it will fail before the pre-save hook runs and has a chance to fill in the fooSort value. It isn't a question of being able to run validation again manually.

Again, if you want to validate something and then need the hook for post validate:

UserSchema.post('validate', function(next){
    console.log("post validate called");
    next();
});


So for summary, the one difference i see is,
  1. you can use both as long as you get inputs to save in db directly without altering anything (only validation).

  2. If you are altering anything you have to use pre save hook.

like image 170
Naeem Shaikh Avatar answered Oct 21 '22 09:10

Naeem Shaikh


The above answer is incorrect. If you go to: https://github.com/Automattic/mongoose/issues/400 and read the responses to the topic from the mongoose contributor you'll see that he notes they are run before on purpose.

The topic is named: Validation should run after all other pre-save hooks

Mongoose contributor aheckmann states that:

  • right now its running before them
  • not implementing this. validating first gives us a chance to stop before continuing into user defined hooks which may include async updates to other collections.
like image 35
CareBearKate Avatar answered Oct 21 '22 09:10

CareBearKate