Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Validate object against Mongoose schema without saving as a new document

I'm trying to validate some data that will be inserted into a new document, but not before a lot of other things need to happen. So I was going to add a function to the static methods that would hopefully validate objects in an array against he model schema.

Heres the code thus far:

module.exports = Mongoose => {
    const Schema = Mongoose.Schema

    const peopleSchema = new Schema({
        name: {
            type: Schema.Types.String,
            required: true,
            minlength: 3,
            maxlength: 25
        },
        age: Schema.Types.Number
    })

    /**
     * Validate the settings of an array of people
     *
     * @param   {array}     people  Array of people (objects)
     * @return  {boolean}
     */
    peopleSchema.statics.validatePeople = function( people ) {
        return _.every(people, p => {
            /**
             * How can I validate the object `p` against the peopleSchema
             */
        })
    }

    return Mongoose.model( 'People', peopleSchema )
}

So the peopleSchema.statics.validatePeople is where I'm trying to do the validation. I have read through mongooses validation documents, but it doesn't state how to validate against a model without saving the data.

Is this possible?

Update

One of the answers on here pointed me towards the proper validation method, which seems to work, but now its throwing an Unhandled rejection ValidationError.

Heres the static method used to validate data (without inserting it)

peopleSchema.statics.testValidate = function( person ) {
    return new Promise( ( res, rej ) => {
        const personObj = new this( person )

        // FYI - Wrapping the personObj.validate() in a try/catch does NOT suppress the error
        personObj.validate( err => {
            if ( err ) return rej( err )

            res( 'SUCCESS' )
        } )
    })
}

Then heres me testing it out:

People.testValidate( { /* Data */ } )
    .then(data => {
        console.log('OK!', data)
    })
    .catch( err => {
        console.error('FAILED:',err)
    })
    .finally(() => Mongoose.connection.close())

Testing it out with data that doesnt follow the schema rules will throw the error, and as you can see, I try to catch it, but it doesnt seem to work.

P.S. Im using Bluebird for my promises

like image 246
Justin Avatar asked Jan 31 '16 02:01

Justin


People also ask

Does Mongoose save overwrite?

Mongoose save with an existing document will not override the same object reference. Bookmark this question.

Does Mongoose have built-in validation?

Mongoose has several built-in validators. All SchemaTypes have the built-in required validator. The required validator uses the SchemaType's checkRequired() function to determine if the value satisfies the required validator. Numbers have min and max validators.

What is Mongoose unique validator?

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.

What is difference between save and create in Mongoose?

create() is a shortcut for saving one or more documents to the database. MyModel. create(docs) does new MyModel(doc). save() for every doc in docs.


1 Answers

There is one way to do that through Custom validators. When the validation failed, failed to save document into DB.

var peopleSchema = new mongoose.Schema({
        name: String,
        age: Number
    });
var People = mongoose.model('People', peopleSchema);

peopleSchema.path('name').validate(function(n) {
    return !!n && n.length >= 3 && n.length < 25;
}, 'Invalid Name');

function savePeople() {
    var p = new People({
        name: 'you',
        age: 3
    });

    p.save(function(err){
        if (err) {
             console.log(err);           
         }
        else
            console.log('save people successfully.');
    });
}

Or another way to do that through validate() with same schema as you defined.

var p = new People({
    name: 'you',
    age: 3
});

p.validate(function(err) {
    if (err)
        console.log(err);
    else
        console.log('pass validate');
});
like image 186
zangw Avatar answered Sep 23 '22 13:09

zangw