Build a CRUD Operations with Node JS, Express & MongoDB
CRUD stands for Create, Read, Update and Delete. It is a set of operations we get servers to execute (POST, GET, PUT and DELETE respectively). Create means inserting data into the database using INSERT SQL statement. Read means reading data from the database using SELECT SQL statement. Update means updating records using the UPDATE SQL query. Finally, Delete means deleting data from database using DELETE SQL statements.
In this tutorial, We will share how to Build CRUD Operations with Node JS, Express, and MongoDB. This is a very simple example, you can just copy paste and change according to your requirement.
Before started to implement the Newsletter Email Subscription with PHP and MySQL, look files structure:
- crud-operation-in-nodejs-with-mongodb
- models
- DBconfig.js
- emp.model.js
- controllers
- empController.js
- package.json
- server.js
- node_modules
- views
- css
- style.css
- images
- css
- assets
- employee
- addupdate.hbs
- list.hbs
- templates
- mainLayout.hbs
- employee
- models
Step 1: Create Project
First, we will create a application directory crud-operation-in-nodejs-with-mongodb.
1 |
$ mkdir crud-operation-in-nodejs-with-mongodb |
Go to ROOT directory of application and type
npm init
command to initialize our application with a package.json
file.
1 2 3 |
$ cd crud-operation-in-nodejs-with-mongodb // npm command $ npm init |
The
package.json
file will be created at the ROOT of application directory.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
{ "name": "crud-operation-in-nodejs-with-mongodb", "version": "1.0.0", "description": "Build a CRUD Operations with Node JS, Express, and MongoDB", "main": "server.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [ "crud", "operations" ], "author": "TechArise Team", "license": "MIT", "dependencies": { "body-parser": "^1.19.0", "express": "^4.17.1", "express-handlebars": "^3.1.0", "mongoose": "^5.9.2" }, "devDependencies": { "handlebars": "^4.5.0" } } |
Change main file from
index.js
file to server.js
that we will create later as it will be entry point of application. Step 2: Install Project Dependencies
1 2 |
// Install Project Dependencies $ npm i --s express@4.17.1 mongoose@5.9.2 express-handlebars@3.1.0 body-parser@1.19.0 |
Dependencies will be added in the
package.json
file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
{ "name": "crud-operation-in-nodejs-with-mongodb", "version": "1.0.0", "description": "Build a CRUD Operations with Node JS, Express, and MongoDB", "main": "server.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [ "crud", "operations" ], "author": "TechArise Team", "license": "MIT", "dependencies": { "body-parser": "^1.19.0", "express": "^4.17.1", "express-handlebars": "^3.1.0", "mongoose": "^5.9.2" }, "devDependencies": { "handlebars": "^4.5.0" } } |
There will also be node_modules folder added at the root of our application with Node modules.
Create DB config file
Create a config file named DBconfig.js
inside “models” folder.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
const mongoose = require('mongoose'); mongoose.connect('mongodb://localhost:27017/techarise_DB', { useNewUrlParser: true }, (err) => { if (!err) { console.log('Connection created.') } else { console.log('Connection failed: : ' + err) } }); // employee model require('./emp.model'); |
Create a model file
Create a model file named
emp.model.js
inside “models” folder.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
const mongoose = require('mongoose'); // employeeSchema var empSchema = new mongoose.Schema({ full_name: { type: String, required: 'Please enter full name.' }, email: { type: String }, mobile: { type: String }, address: { type: String }, salary: { type: String } }); // email validation empSchema.path('email').validate((val) => { emailRegex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; return emailRegex.test(val); }, 'Please enter valid e-mail addtess.'); mongoose.model('empModel', empSchema); |
Create a controller file
Create a controller file named
empController.js
inside “controllers” folder.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
const express = require('express'); var router = express.Router(); const mongoose = require('mongoose'); const Employee = mongoose.model('empModel'); router.get('/', (req, res) => { res.render("employee/addupdate", { viewTitle: "Insert Employee" }); }); router.post('/', (req, res) => { if (req.body._id == '') insertRecord(req, res); else updateRecord(req, res); }); function insertRecord(req, res) { var employee = new Employee(); employee.full_name = req.body.full_name; employee.email = req.body.email; employee.mobile = req.body.mobile; employee.address = req.body.address; employee.salary = req.body.salary; employee.save((err, doc) => { if (!err) res.redirect('employee/list'); else { if (err.name == 'ValidationError') { handleValidationError(err, req.body); res.render("employee/addupdate", { viewTitle: "Create Employee", employee: req.body }); } else console.log('Error during record insertion : ' + err); } }); } function updateRecord(req, res) { Employee.updateOne({ _id: req.body._id }, req.body, { new: true }, (err, doc) => { if (!err) { res.redirect('employee/list'); } else { if (err.name == 'ValidationError') { handleValidationError(err, req.body); res.render("employee/addupdate", { viewTitle: 'Update Employee', employee: req.body }); } else console.log('Error during record edit : ' + err); } }); } router.get('/list', (req, res) => { Employee.find((err, docs) => { if (!err) { res.render("employee/list", { emplist: docs }); } else { console.log('Error in retrieving emp list :' + err); } }); }); function handleValidationError(err, body) { for (field in err.errors) { switch (err.errors[field].path) { case 'full_name': body['full_nameError'] = err.errors[field].message; break; case 'email': body['emailError'] = err.errors[field].message; break; default: break; } } } router.get('/:id', (req, res) => { Employee.findById(req.params.id, (err, doc) => { if (!err) { res.render("employee/addupdate", { viewTitle: "Update Employee", employee: doc }); } }); }); router.get('/delete/:id', (req, res) => { Employee.findByIdAndRemove(req.params.id, (err, doc) => { if (!err) { res.redirect('/employee/list'); } else { console.log('Error in employee remove :' + err); } }); }); module.exports = router; |
Create a view file
Create a view file named
addupdate.hbs
inside “views/employee” folder.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
<section class="showcase"> <div class="container"> <div class="pb-2 mt-4 mb-2 border-bottom"> <h2>Build a CRUD Operations with Node JS, Express, and MongoDB</h2> </div> <div class="row"> <div class="col-sm-10 offset-md-1"> <form action="/employee" method="POST" autocomplete="off"> <input type="hidden" name="_id" value="{{employee._id}}"> <div class="form-row"> <div class="form-group col-md-6"> <label>Full Name</label> <input type="text" class="form-control" name="full_name" placeholder="Full Name" value="{{employee.full_name}}"> <div class="text-danger"> {{employee.full_nameError}}</div> </div> <div class="form-group col-md-6"> <label>Email</label> <input type="text" class="form-control" name="email" placeholder="Email" value="{{employee.email}}"> <div class="text-danger"> {{employee.emailError}}</div> </div> </div> <div class="form-group"> <label>Address</label> <textarea class="form-control" name="address" placeholder="Address">{{employee.address}}</textarea> </div> <div class="form-row"> <div class="form-group col-md-6"> <label>Mobile</label> <input type="text" class="form-control" name="mobile" placeholder="Mobile" value="{{employee.mobile}}"> </div> <div class="form-group col-md-6"> <label>Salary</label> <input type="text" class="form-control" name="salary" placeholder="Salary" value="{{employee.salary}}"> </div> </div> <div class="form-group float-right"> <button type="submit" class="btn btn-primary btn-sm"><i class="fa fa-database"></i> Submit</button> <a class="btn btn-info btn-sm" href="/employee/list"><i class="fa fa-list-alt"></i> View All</a> </div> </form> </div> </div> </div> </section> |
Create a view file named
list.hbs
inside “views/employee” folder.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
<section class="showcase"> <div class="container"> <div class="pb-2 mt-4 mb-2 border-bottom"> <h2>Build a CRUD Operations with Node JS, Express, and MongoDB <a class="btn btn-info float-right btn-sm" href="/employee"><i class="fa fa-plus"></i> Create New</a></h2> </div> <div class="row"> <div class="col"> <table class="table table-striped"> <thead> <tr> <th>Full Name</th> <th>Email</th> <th>Mobile</th> <th>Address</th> <th>Salary</th> <th>#</th> </tr> </thead> <tbody> {{#each emplist}} <tr> <td>{{this.full_name}}</td> <td>{{this.email}}</td> <td>{{this.mobile}}</td> <td>{{this.address}}</td> <td>{{this.salary}}</td> <td> <a href="/employee/{{this._id}}"><i class="fa fa-edit" aria-hidden="true"></i></a> <a href="/employee/delete/{{this._id}}" onclick="return confirm('Are you sure to delete this record ?');"><i class="fa fa-trash" aria-hidden="true"></i></a> </td> </tr> {{/each}} </tbody> </table> </div> </div> </div> </section> |
Create files named (mainLayout.hbs)
This file contains the mainLayout section of the webpage. The Bootstrap library is used to provide a better UI.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <link rel="icon" type="image/ico" href="/static/images/favicon.ico"> <meta name="description" content=""> <meta name="author" content=""> <title>Build a CRUD Operations with Node JS, Express, and MongoDB | Tech Arise</title> <!-- Bootstrap core CSS --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.min.css" /> <!-- Custom fonts for this template --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.7.2/css/all.min.css" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/simple-line-icons/2.4.1/css/simple-line-icons.css" /> <link href="https://fonts.googleapis.com/css?family=Lato:300,400,700,300italic,400italic,700italic" rel="stylesheet" type="text/css"> <!-- Custom styles for this template --> <link href="/static/css/style.css" rel="stylesheet"> </head> <body> <!-- Navigation --> <nav class="navbar navbar-expand-lg navbar-dark bg-dark static-top header-bg-dark"> <div class="container"> <a class="navbar-brand font-weight-bold" href="https://techarise.com"> <h1>Tech Arise</h1> </a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarResponsive"> <ul class="navbar-nav ml-auto"> <li class="nav-item active"> <a class="nav-link" href="https://techarise.com">Home <span class="sr-only">(current)</span> </a> </li> <li class="nav-item"> <a class="nav-link" href="https://techarise.com/php-free-script-demos/">Live Demo</a> </li> </ul> </div> </div> </nav> {{{body}}} <!-- Footer --> <footer class="footer bg-light footer-bg-dark"> <div class="container"> <div class="row"> <div class="col-lg-6 h-100 text-center text-lg-left my-auto"> <ul class="list-inline mb-2"> <li class="list-inline-item"> <a href="#">About</a> </li> <li class="list-inline-item">⋅</li> <li class="list-inline-item"> <a href="#">Contact</a> </li> <li class="list-inline-item">⋅</li> <li class="list-inline-item"> <a href="#">Terms of Use</a> </li> <li class="list-inline-item">⋅</li> <li class="list-inline-item"> <a href="#">Privacy Policy</a> </li> </ul> <p class="text-muted small mb-4 mb-lg-0">Copyright © 2011 - <?php print date('Y', time());?> <a href="https://techarise.com/">TECHARISE.COM</a> All rights reserved.</p> </div> <div class="col-lg-6 h-100 text-center text-lg-right my-auto"> <ul class="list-inline mb-0"> <li class="list-inline-item mr-3"> <a href="#"> <i class="fab fa-facebook fa-2x fa-fw"></i> </a> </li> <li class="list-inline-item mr-3"> <a href="#"> <i class="fab fa-twitter-square fa-2x fa-fw"></i> </a> </li> <li class="list-inline-item"> <a href="#"> <i class="fab fa-instagram fa-2x fa-fw"></i> </a> </li> </ul> </div> </div> </div> </footer> </body> </html> |
Step 3: Setup Application Server.js file
We will create
server.js
file at the ROOT of application. We will add following code to our server.js
file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
require('./models/DBconfig'); const express = require('express'); const path = require('path'); const exphbs = require('express-handlebars'); const bodyparser = require('body-parser'); const empController = require('./controllers/empController'); var app = express(); app.use(bodyparser.urlencoded({ extended: true })); // file static path app.use('/static', express.static(path.join(__dirname, 'assets/'))); app.use(bodyparser.json()); app.set('views', path.join(__dirname, '/views/')); app.engine('hbs', exphbs({ extname: 'hbs', defaultLayout: 'mainLayout', layoutsDir: __dirname + '/views/templates/' })); app.set('view engine', 'hbs'); app.listen(3000, () => { console.log('SERVER is listening on PORT 3000'); }); app.use('/employee', empController); |
Note: At the top of file, we will import the required modules.
Run Server following command:
1 |
$ node server.js |
Nodemon restarts the server automatically whenever you save a file that the server uses:
1 |
$ nodemon server.js |
CRUD Operations with Node JS, Express, and MongoDB – Output
List Employee screen
Create Employee screen