Home > Net >  Validation not working on mongoose schema
Validation not working on mongoose schema

Time:11-04

When I add data to my db mongoose is not validating the data types that I have defined on Schema:

The Schema:

const mongoose = require("mongoose");

const Postschema = new mongoose.Schema({
  nome: {
    type: String,
    required: true,
    trim: true
  },
  email: {
    type: String,
    required: true,
    trim: true
  },
  morada: {
    type: String,
    required: true,
    trim: true
  }
});

const Post = mongoose.model('Post', Postschema);

module.exports = Post

The function:

const store = (req, res) => {
  const post = new Post({ nome: req.body.nome, email: req.body.email, morada: req.body.morada });
  post.save().then((post) => {
    res.status(201).json(post)
  }).catch((e) => res.status(500).json(e))
}

So even if I try to create and store a document with number instead of string (as it is shown below) it still works even after I defined that it has to be a string in the Schema and the object get stored with the wring type of data.

{
    "nome": 1,
    "email":"Associado",
    "morada":"[email protected]"    
}

As you can see, nome should be a string, but I could add it to my db as an integer. What am I doing wrong?

CodePudding user response:

you defined nome as a string but you are inserting nome as an integer

{
    "nome": 1,
    "email":"Associado",
    "morada":"[email protected]"    
}

you should send data as below

{
    "nome": "1",
    "email":"Associado",
    "morada":"[email protected]"    
}

or convert nome to the string before inserting like this

 const post = new Post({ nome: req.body.nome.toString(), email: req.body.email, morada: req.body.morada });

or if you want to save nome as number change your schema type of nome to Number like this

nome: {
    type: Number,
    required: true,
    trim: true
  },

CodePudding user response:

In that case the nome field from the body is interpreted as a string and the Post document is created.

If you need to validate post requests you should use the express-validator library and define a custom middleware for handling the body fields:

  1. Define a validator.js middleware:
const { body } = require('express-validator');

const validate = (method) => {
  switch (method) {
    case 'store': {
      return [
        body('nome')
          .not()
          .isEmpty()
          .withMessage('Nome is required')
          .not()
          .isNumeric()
          .withMessage('Nome should be a string')
          .trim()
          .escape(),
        body('email')
          .not()
          .isEmpty()
          .withMessage('E-mail is required')
          .isEmail()
          .withMessage('Insert a valid e-mail')
          .normalizeEmail(),
        body('morada')
          .not()
          .isEmpty()
          .withMessage('Morada is required')
          .trim()
          .escape(),
      ];
    }
    default:
      break;
  }
};

module.exports = { validate };
  1. Add the validate function to the store method definition as a middleware:
const { validate } = require('./validator')

// Express router setup...

router.post('/url/to/post/store', validate('store'), store)
  1. You can handle validation errors in your store function by accessing the validationResult function. In case of errors it will return a non empty set.
const { validationResult } = require('express-validator');

const store = (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
        return res.status(400).json({ errors: errors.array() });
    }

    ...
};
  • Related