NodeJs Server Side Form Validation using Express-Validator, Body-Parser and EJS
Today we are going to do some server-side form validation using the Express-validator, Body-parser and for the view engine, I will be using EJS. This is an introduction video, but it should give you enough knowledge to get you started with form validation.
As you might already know it’s usually good practice to validate user input on Server Side because you can protect against malicious users, who can easily bypass your client-side scripting language and submit dangerous input to the server.
Before we get started with this project you need to have NodeJs installed.
Before we get started, I just wanted to mention that you can also watch the full video if you prefer that format. If you like the content, I would appreciate it if you subscribe to my channel here.
Create a project folder
Let’s get started by creating a folder with your project name. This is where your project is going to live and all packages are installed. Talking about packages, let’s go to the next step and create our server setup.
Setup Server Yo!
To start with our project we need to first generate a file called package.json. It holds various metadata relevant to the project and it’s used to give information to npm that allows identifying the project as well as handle dependencies. Go to the root of the folder, open PowerShell or Terminal and type the following command:
npm init
As long as you have NodeJs installed, this should guide you through the setup of your project. Basically answer the required questions in the terminal or just keep pressing enter if you are messing around.
Once you finish with the installation, open your package.json file and just double check to see if everything is looking good.
Now let’s install some dependencies.
Install Dependencies
The dependencies that we need to install are:
- Express
- EJS
- Express-Validator
- Nodemon – nice to have
- Body-parser
I’ve linked each dependency to their official documentation so you can go and explore. I strongly encourage you to do that to see what’s possible.
The alternative templating engine that you can use is PUG. Pug is also nice, but I am getting used to EJS now and I almost like it.
Another important thing that you might want to know is that the bodyParser is no longer bundled as part of Express and so we’ll have to install that too.
Let’s install the dependencies by running the following command in the same project folder of course.
npm install express ejs express-validator nodemon body-parser
Project Structure
Now let’s create the following project structure, leaving node_modules, readme.md, package-lock and package-json as that should have been automatically generated by now.
π node_modules π views π register.ejs π index.ejs π README.md π app.js π package-lock.json π package-json
Setup Nodemon
Before we run our server to see if everything is working as intended, we need to add some more metadata in our package.json file. We need to add Nodemon to start the app as we don’t have to refresh every time we make changes.
Open your package.json file and add the following under scripts
"start": "nodemon app.js"
Your full JSON file should look something like this (obviously you might have newer versions of the packages):
{ "name": "express-validator-tut", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "nodemon app.js" }, "author": "", "license": "ISC", "dependencies": { "body-parser": "^1.19.0", "ejs": "^3.1.3", "express": "^4.17.1", "express-validator": "^6.6.1" }, "devDependencies": { "nodemon": "^2.0.4" } }
Save the file and now you should be able to run your project by simply doing:
npm start
We are getting close, but there are a few more things that we need to do before we are able to see our project. First, we need to add ‘express’ and select a port that NodeJs can listen to. Let’s do that.
In your app.js folder add the following code:
// Imports const express = require('express') const app = express() const port = 5000 // Listen on Port 5000 app.listen(port, () => console.info(`App listening on port ${port}`))
Run your app, and see what happens. To do that you can go in your Terminal and type the following command:
npm start
In PowerShell or Terminal (for Mac) you should see a message:
App listening on port 5000 – unless the port is already taken, then you can change it to 3000 or something like that.
Now if you go on your Internet Browser and visit the URL localhost:5000 you should see a message saying:
Cannot GET /
That’s good. Let’s carry on and fix that.
BodyParser
Include the body parser just after you require express:
const bodyParser = require('body-parser')
There are different modules that we can use such as JSON body-parser, Raw body-parser, text body-parser and url-encoded form body-parser, but today we are going to use the Url-encoded form body-parser.
Add the following code after you set your View engine:
const urlencodedParser = bodyParser.urlencoded({ extended: false })
Setting Up Our Templating Language
In this application, we are going to work with EJS. There are a lot of options out there that you can choose from and most of them are fairly similar. Here is how we can set our templating language using EJS.
// Set View's app.set('view engine', 'ejs');
const bodyParser = require('body-parser') const { check, validationResult } = require('express-validator')
Validation Checks
To perform validation checks is actually fairly simple. We need to require the express validator at the top of our project (under the body-parser) and then we should be able to use it on POST. Let’s first require the express validator:
const { check, validationResult } = require('express-validator')
Now let’s create a very simple post route:
app.post('/register', urlencodedParser, [ check('username', 'This username must me 3+ characters long') .exists() .isLength({ min: 3 }), check('email', 'Email is not valid') .isEmail() .normalizeEmail() ], (req, res)=> { const errors = validationResult(req) if(!errors.isEmpty()) { // return res.status(422).jsonp(errors.array()) const alert = errors.array() res.render('register', { alert }) } })
Our Final Code for APP.JS
const express = require('express') const bodyParser = require('body-parser') const { check, validationResult } = require('express-validator') const app = express() const port = 5000 // Set Templating Enginge app.set('view engine', 'ejs') const urlencodedParser = bodyParser.urlencoded({ extended: false }) // Navigation app.get('', (req, res)=> { res.render('index') }) app.get('/register', (req, res)=> { res.render('register') }) app.post('/register', urlencodedParser, [ check('username', 'This username must me 3+ characters long') .exists() .isLength({ min: 3 }), check('email', 'Email is not valid') .isEmail() .normalizeEmail() ], (req, res)=> { const errors = validationResult(req) if(!errors.isEmpty()) { // return res.status(422).jsonp(errors.array()) const alert = errors.array() res.render('register', { alert }) } }) app.listen(port, () => console.info(`App listening on port: ${port}`))
Register.ejs Page
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Register</title> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous"> </head> <body> <div class="container"> <h1>Register</h1> <% if(typeof alert != 'undefined') { %> <% alert.forEach(function(error) { %> <div class="alert alert-warning alert-dismissible fade show" role="alert"> <%= error.msg %> <button type="button" class="close" data-dismiss="alert" aria-label="Close"> <span aria-hidden="true">Γ</span> </button> </div> <% }) %> <% } %> <form action="/register" method="POST"> <div class="form-group"> <label for="username" class="form-label">Username</label> <input type="text" class="form-control" name="username" id="username"> </div> <div class="form-group"> <label for="email" class="form-label">Email address</label> <input type="email" class="form-control" name="email" id="email"> </div> <div class="form-group"> <label for="password" class="form-label">Password</label> <input type="password" class="form-control" name="password" id="password"> </div> <div class="form-group"> <label for="password1" class="form-label">Confirm Password</label> <input type="password" class="form-control" name="password1" id="password1"> </div> <button type="submit" class="btn btn-primary">Submit</button> </form> </div> </body> </html>
That’s all!
I hope that you found this article helpful. It was written fairly quickly but I will try to revisit it and make it a little bit more organised. If you would like to see more articles and videos like this please consider subscribing to my YouTube channel here.
YouTube Update
If you would like to make the highlighted Bootstrap close alert buttons work you need to include the Bootstrap JS files below. Place one of the following <script>
s near the end of your pages, right before the closing </body>
tag, to enable them. jQuery must come first, then Popper.js, and then our JavaScript plugins.
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx" crossorigin="anonymous"></script>
For example, your Register.ejs should look something like this:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Register</title> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous"> </head> <body> <div class="container"> <h1>Register</h1> <% if(typeof alert != 'undefined') { %> <% alert.forEach(function(error) { %> <div class="alert alert-warning alert-dismissible fade show" role="alert"> <%= error.msg %> <button type="button" class="close" data-dismiss="alert" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <% }) %> <% } %> <form action="/register" method="POST" novalidate> <div class="form-group"> <label for="username" class="form-label">Username</label> <input type="text" class="form-control" name="username" id="username"> </div> <div class="form-group"> <label for="email" class="form-label">Email address</label> <input type="email" class="form-control" name="email" id="email"> </div> <div class="form-group"> <label for="password" class="form-label">Password</label> <input type="password" class="form-control" name="password" id="password"> </div> <div class="form-group"> <label for="password1" class="form-label">Confirm Password</label> <input type="password" class="form-control" name="password1" id="password1"> </div> <button type="submit" class="btn btn-primary">Submit</button> </form> </div> <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx" crossorigin="anonymous"></script> </body> </html>
More Resources:
I got an error where error is *ReferenceError: alert is not defined*.
I have view your Server side form validation video, and what to do for removing this error
Hi Dilkash,
You have to define “alert” like the example below:
const alert = errors.array()
res.render('register', {
alert
})
how to give success message registered successfully
There are many ways you can do it. Check if your errors array is empty and then add your “Success” message into the alert const. You could push a new object with your alert message. So it might be a case of just adding an if check.
How to show errors under each input fields using nodejs with express-validator?
You can use the bootstrap form validation. Just make sure you include the Bootstrap JS file in your project.
The final error message is not showing above the login form . only blank space is showing
“Email is not valid” is not showing? I just downloaded the code from GitHub and it seems okay. Can you share your code?
My register page is in .pug template format . What is the format for displaying alert .
You can view their documentation here: https://pugjs.org/api/getting-started.html
Must allow the user to add their own textual content onto a dedicated section of the website. Whatever text is written by the user must be sent to the server (through Node.js) and checked for any forbidden words. If there arenβt any forbidden words, the text is added to the dedicated section of the website; otherwise, the text is not added. What words are forbidden is up to you. Note that the text will be checked by calling a method from an object created from a JavaScript class, Y. If the text passes the check, it is then passed to a method that is defined in class X (mentioned above). That method will then write the text onto the website.
Can you help me figure out this website criteria?
Do you have a specific question? The best way to learn is to try your best to figure it all out for yourself. Keep on searching for the problems that you encounter and in the end, you will learn so much and be proud of what you’ve accomplished. Always here to guide, but I can’t give you the answers
hello, after adding my script at the end of my register.ejs page, my alert messages are not getting remove.
That’s strange. If you inspect your source code is the script there?
maximum call stack size exceeded error occurs
the part to validate the confirm password against the password is not recorded. Nice tutorial though. thumbs up, bro.
Thanks brother!