Validation in Mongoose(where, how and handle errors)

Yingqi Chen
3 min readJun 13, 2020

Recently I am building an app to practice my Node.js and Express.js skills, which is connected with MongoDB with Mongoose. My progress is slow because I want to take my time to learn any new point instead of just getting the job done.

Today, I want to implement the validation in my app. So I have been researching and looking up in the documentation. The validation is not too complicated in my app, but I want to write down some notes here for my future reference! And hope this will help you too!

Mongoose validator

In this article, I want to give you some examples. But if you want to save some time and go straight to the point, go to the document would be the best way.

Mongoose validator will be my second layer of validation, so even the data passes the route validator, it will not be able to persist in my database. You don’t have to install anything because it comes with Mongoose.

Where

First of all, the validation of models should be put in the file where the mongoose.Schema is used to create a certain model because validation is defined in the SchemaType. You should put the validator into when you define the property, like so:

const eventSchema = mongoose.Schema({  name: {    type: String,    required: [true, 'A name is required.'], //validator  }
})

How

There are built-in validators and custom validators.

  1. Built-in validators

Mongoose has several built-in validators for different SchemaTypes.

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.

Strings have enum, match, minlength, and maxlength validators.

The validator usually looks like this: validator: [expectation, message] . The expectation will be something you expect, and the message will be something you return along with the error.

const eventSchema = mongoose.Schema({  name: {    type: String,    required: [true, 'A name is required.'], }
})

In this case, if you want to create an event without a name, you will get an error:

"Event validation failed: name: A name is required."

As you can see, the message in the array “A name is required” is displayed along with the error.

2. Custom validators

Great documentation is presented to talk about the validate function in SchemaType if you want more details.

The format would be:

const Schema = mongoose.Schema({
name: {
type: String,
validate: {
validator: function(v){
return <expectation>
},
message: props => `${props.path} should be..., got '${props.value}'`;
}
})

The expectation should be something you expect the data to be, and to custom the error message, you could use the props that are passed in and access its path(which is ‘name’ here) and the value , which is the value of name when the request is submitted.

Error handle

In the case above,

const eventSchema = mongoose.Schema({   name: {     type: String,     required: [true, 'A name is required.'],  }
})

If you try to create an event without a name, the error object would look like this:

{"errors": {  "name": {    "properties": {    "message": "A name is required.",    "type": "required",    "path": "name"    },    "kind": "required",    "path": "name"  } },"_message": "Event validation failed","message": "Event validation failed: name: A name is required."}

You can use whatever way you like to print out the errors. But make sure you handle it in a try...catch block, like so:

router.post('/events', async (req, res) => {  event = new Event(req.body);  event.ownerId = req.params.id;  try {    const result = await event.save();    res.json(result);  } catch (err) {    res.json(err.errors.message);  }});

End

There is a lot more information about validation that I haven’t covered, including to make async validation, required validators on nested objects, validators for update operations, etc. I would strongly recommend you to read the documentation to find out more interesting stuff! Thanks for reading!

--

--

Yingqi Chen

Software engineer and a blockchain noob. Excited about the new world!!LinkedIn:https://www.linkedin.com/in/yingqi-chen/