Mongoose (validation + hooks = 🔥)
How mongoose inbuilt validations and hooks can be powerful at times and much more
Mongoose is an ODM(Object Document Modeler) for the mongo DB database. It provides ease such as built-in casting, query building, validations, and more.
Validations
You must have used joi for schema validation in express, but why to use heavy packages such as joi if we can validate using mongoose, now we will see how to use the mongoose validate function to validate schemas.
Here I have created a simple route to register a new user:
// *NEW USER ROUTEapp.post("/register", async (req, res) => {try {const user = await User.create(req.body);res.json({ success: true, message: "User saved successfuly!!" });} catch (e) {return res.status(400).json({ success: false, messge: e.message });}});
User Model:
const mongoose = require("mongoose");const bcrypt = require("bcryptjs");const User = new mongoose.Schema({name: {type: String,required: true,},email: {type: String,required: true,unique: true,},phone: {type: String,required: true,
},password: {type: String,required: true},});module.exports = mongoose.model("user", User);
If you want custom error messages:
....
required: [true, "phone number is required"]
....
Note: unique is not a validator
Adding validation
Mongoose uses an inbuilt validation function that validates the schema and also returns a custom message.
(ps: validating contact length)
“Entered input is passed to the message as an argument”
phone: {type: String,required: [true, "Phone number is required !"],validate: {validator: (v) => {return v.length == 10;},message: (props) => props.value + " Must be 10 digits !",},},
Using regex :
email: {type: String,required: [true, "email is required !!"],unique: true,validate: {validator: (email) => {const pattern = /^[A-Z0-9._%+-]+@([A-Z0-9-]+\.)+[A-Z]{2,4}$/i;return pattern.test(email);},message: (props) => `${props.value} is not in correct format !!`,},},
Now, while creating a new user you need not to worry about validation, mongoose will handle and throw validations, accordingly !!

Similarly when using incorrect email:

Et voila! Goodbye, joi.
Next Step: Using mongoose hooks
There are mainly two mongoose hooks that are widely used:
- “pre”: does Something before saving the model.
- “post”: does something after saving the model.
Using hooks/middlewares:
If we console log this inside pre hook, we get the req.body or what the user entered.

Let's hash the password before saving it to the database using bcrypt library.

as pre is a middleware, it takes next as an argument and can also return promises, after successful completion, it calls next() middleware.
Let’s see if that worked …

Now our password is hash and we didn’t do any changes to our controller.
Similarly post hook works after saving the model.
Events that middleware can take:
- “save”
- “remove”
- “validate”
And more.
Final source code: link
If you have reached here, thank you for reading this article I hope it clears the use of mongoose validations and middle-wares/hooks. If you liked it don’t forget to leave an applaud.
Thank you!