Thursday, January 18, 2018

mongoose custom Validations

The great advantages of using Mongoose over plain MongoDB is that its built-in support for data schemas, and hence automatic validation of data when it is saved or updates. here we will see on that page how to configure custom validators / validations in the latest version(4.0) of Mongoose.

Mongoose’s validators are too easy to configure. When defining your schema, you can add extra options to the property that you want to be validated, but sometimes we required to make validation our own and validate specified fields as per our requirement.

if your one field's validation depends on another field then you must have to use custom validation.

EX: Demo

/*
 * User model to store users information
*/
var mongoose = require('mongoose'),
      Schema = mongoose.Schema;

var userSchema = new Schema({
    user_name: {
        type: String, // Unique username for sign up
    },
    first_name: {
        type: String,
        index: true
    },
    last_name: {
        type: String,
        index: true
    },
    gender: {
        type: String,
        enum: ['Male', 'Female'],
        index: true
    },
    email: {
        type: String, // Unique Email for sign up
    },
    password: {
        type: String, // Password
        //select: true
    },
    is_active: {
        type: Number,
        default: -1
    },
    created_at: {
        type: Date,
        default: Date.now
    }, // Registration date
    updated_at: {
        type: Date,
        default: Date.now
    },
}, {collection: 'user'});

/**
 *Custom Validations
*/

/**
 *Simple custom Validations
*/
userSchema.path('user_name').required(true, 'user name is required.');
userSchema.path('email').required(true, 'email is required.');
userSchema.path('password').required(true, 'password is required.');
userSchema.path('is_active').required(true, 'is active is required.');
userSchema.path('gender').required(true, 'gender is required.');

/**
*Complex custom Validations
*/
userSchema.path('user_name').validate(function (value, cb) {
    var regex = /^(?=.*[a-zA-Z]+)([a-zA-Z0-9_]){4,15}$/;
    if (regex.test(value) === false) {
        return cb(false);
    } else {
        cb(true);
    }
}, 'Your user name can only contain letters (a-z), numbers, and underscore ( _ ).');

userSchema.path('email').validate(function (value, cb) {
        this.model('User').count({email: value}, function (err, count) {
            if (err)
                return cb(err);
            // If `count` is greater than zero, "invalidate"
            cb(!count);
        });
}, 'Email already exists');

userSchema.path('user_name').validate(function (value, cb) {
        this.model('User').count({user_name: value}, function (err, count) {
            if (err)
                return cb(err);
            // If `count` is greater than zero, "invalidate"
            cb(!count);
        });
}, 'User name already exists');

/*
 *Define model and export it for use in other page
 */
var User = mongoose.model("User", userSchema);
module.exports = User;

Unlike some other ORMs, Mongoose does not have more complicated validations, such as email, user_name, gender, etc.

We can also perform a custom validation by using the required or validate property.

path property is used to define field name for custom validation.We can pass only one field name at a time means we can not pass a field in the array with path property.

=>required
required property is used weather given filed will compulsory or not.In this required property there are two parameters, first is for validation true or false, and second for the custom message.
if the field is invalid the required function should return false otherwise it should return true.

=>validate
validate property is used to make your own validation as you want.By using you can also do validation with two or more fields.
in validate property, the first parameter contains the function with current value and callback, and in a second you can pass a custom message.

=>How to validate
You can validate by using model validate method.when every your data save means at creating and update mongoose automatically check validation, and if any error occurs then a model date will not save.

EX: api.js

var express = require('express');
var router = express.Router();
var User = require('../models/user');

/*
*user register api
*/
router
        .route('/api/user/register')
        .post(
                function (req, res, next) {
                    var userData;
                    userData = {
                        user_name: req.body.userName,
                        first_name: req.body.firstname,
                        last_name: req.body.lastname,
                        gender: req.body.gender,
                        email: req.body.email,
                        password: req.body.password
                    };

                    userModel = new User(userData);
                    userModel.validate(function (err) {
                        if (err) {
                            res.json({status: 0, code: 200, type: "error", message: err});
                        } else {
                            userModel.save(function(err, userModel){
                              if (err) {
                                res.json({status: 0, code: 200, type: "error", message: err});
                            }else{
                                   res.json({status: 0, code: 200, type: "success", message: "user registered success"});
                            }
                            })
                        }
                    });
           });

module.exports = router;

From this, we can say that mongoose provides good feature to add custom validation user-friendly.

No comments:

Post a Comment