- A Request is sent to the server and handled by the application controllers.
- Express.js and its routes can behave like controllers handling requests and determining whether to process the request further or send back a response.
- The routes may also trigger more code logic in other modules, communicate with database, or render a view.
- The client receives a response after the controller decides to generate views to send back.
- express: Fast,
efficient, minimalist web framework for node.
- body-parser: Node.js body parsing middleware.
- express-handlebars: A Handlebars view engine for Express.
- mongoose: Mongoose is a MongoDB object modeling tool designed to work in an asynchronous environment.
- Open Mongod Server
- Open MongoDB Compass Community
- Create database "studentDB" and a collection "students"
Output in Browser- http://localhost:3000/student
Step-10: Now update server.js for Configuring Express Handlebars.
server.js
// Import Express Handlerbar
const path = require('path');
const exphbs = require('express-handlebars');
// Configure View Engine
app.set('views', path.join(__dirname, '/views/'));
app.engine(
'hbs',
exphbs({
extname: 'hbs',
defaultLayout: 'mainLayout',
layoutsDir: __dirname + '/views/layouts/',
})
);
app.set('view engine', 'hbs');
Step-11: For Views, create another folder in your application folder as "views" and then create folder "layouts" inside, that
store our main layout, Create a file mainLayout.hbs.
mainLayout.hbs
<!DOCTYPE html>
<html lang="en">
<head>
<title>NodeJS Express MongoDB CRUD</title>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet">
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
</head>
<body class="bg-secondary">
<div class="row">
<div class="col-md-8 offset-md-2" style="background-color: white; padding:20px; margin-top:25px;">
{{!-- this inherit our view --}}
{{{body}}}
</div>
</div>
</body>
</html>
Step-12: For Views, create folder "student" in your "views" folder that stores our view. Create a file as addOrEdit.hbs handlebar.
addOrEdit.hbs
<h3>{{viewTitle}}</h3>
<form>
<div class="form-group">
<label>Full Name</label>
<input type="text" class="form-control" name="fullName" placeholder="Full Name">
<div class="form-group">
<label>Email</label>
<input type="text" class="form-control" name="email" placeholder="Email">
<div class="form-row">
<div class="form-group col-md-6">
<label>Mobile</label>
<input type="text" class="form-control" name="mobile" placeholder="Mobile">
</div>
<div class="form-group col-md-6">
<label>City</label>
<input type="text" class="form-control" name="city" placeholder="City">
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-info"><i class="fa fa-database"></i> Submit</button>
</div>
</form>
Step-13: Now update studentController.js for rendering the above view.
studentController.js
const express = require('express');
const router = express.Router();
// render View
router.get('/', (req, res) => {
res.render('student/addOrEdit', {
viewTitle: 'Insert New Student',
});
});
Output in Browser- http://localhost:3000/student
Step-14: Now update the following changes in addOrEdit.hbs form Handlebars, server.js and in studentController.js for posting data.
addOrEdit.hbs
<form method="POST" action="/student" autocomplete="off">server.js
// Import body-parser package const bodyparser = require('body-parser');app.use( bodyparser.urlencoded({ extended: true, }));app.use(bodyparser.json());
studentController.js
router.post('/', (req, res) => {
console.log(req.body);});
Output in Nodemone server: This means data is Posting
[nodemon] starting `node server.js`
App started at 3000
MongoDB Connection Successful
{ fullName: 'Pankaj kapoor',
email: 'pankkap@gmail.com',
mobile: '9729280731',
city: 'Chandigarh' }
Step-15: Now update in studentController.js for posting data into the MongoDb database.
studentController.js
const mongoose = require('mongoose');require('./../models/student.model');const Student = mongoose.model('Student');
router.post('/', (req, res) => { insertRecord(req, res);});
function insertRecord(req, res) { var student = new Student(); student.fullName = req.body.fullName; student.email = req.body.email; student.mobile = req.body.mobile; student.city = req.body.city; student.save((err, docs) => { if (!err) { res.redirect('student/list'); } else { console.log('Error during Record Insertion...' + err); } });}router.get('/list', (req, res) => { res.json('Student List');});Output in Browser- http://localhost:3000/student : Insert your student Data in the Form and press Submit Button, You will be redirected to /student/list display the sample ouput as Student List (This view will be update in the next session). At the same time, data will also be stored in the MongoDB.

Step-16: Now update in studentController.js for reading the list of student's records from MongoDb database and display in /student/list router.
studentController.js
router.get('/list', (req, res) => { Student.find((err, docs) => { if (!err) { res.render('student/list', { list: docs, }); } else { console.log('Error in retrieving employee list :' + err); } });});
Step-17: Now we have to create a new express handlebar that will display the list of students' records.
list.hbs
<h3>Student List</h3><table class="table table-striped"> <thead> <tr> <th>Full Name</th> <th>Email</th> <th>Mobile</th> <th>City</th> <th></th> </tr> </thead> <tbody> {{#each list}} <tr> <td>{{this.fullName}}</td> <td>{{this.email}}</td> <td>{{this.mobile}}</td> <td>{{this.city}}</td> <td> <a><i class="fa fa-pencil fa-lg " aria-hidden="true"></i></a> <a><i class="fa fa-trash fa-lg" aria-hidden="true"></i></a> </td> </tr> {{/each}} </tbody></table>
Step-18: Now we add two buttons in both views one for creating New Student and 2nd View List of students. list.hbs
<h3><a class="btn btn-secondary" href="/student"><i class="fa fa-plus"> </i> Create New</a> Student List</h3>
addOrEdit.hbs
<a class="btn btn-secondary" href="/student/list"><i class="fa fa-list-alt"> </i> View All</a>
Step-19: When using express Handlebar, there is an error in retrieving data from the database.
[nodemon] starting `node server.js`App started at 3000MongoDB Connection SuccessfulHandlebars: Access has been denied to resolve the property "fullName" because it is not an "own property" of its parent.
This issue can be resolved by adding the following code in server.js file.
const Handlebars = require('handlebars');const { allowInsecurePrototypeAccess,} = require('@handlebars/allow-prototype-access');
// Configure View Engineapp.set('views', path.join(__dirname, '/views/'));app.engine( 'hbs', exphbs({ extname: 'hbs', defaultLayout: 'mainLayout', layoutsDir: __dirname + '/views/layouts/',
// Issue in Access has been denied to resolve the property //"---" because it is not an "own property" of its parent. handlebars: allowInsecurePrototypeAccess(Handlebars), }));app.set('view engine', 'hbs');
Output in Browser- http://localhost:3000/student/list
Step-20: Now we create a new route in studentController.js for Edit Button to update the previously stored record.
studentController.js: This will open the view for update the previous record with ViewTitle proper: Update student
router.get('/:id', (req, res) => { Student.findById(req.params.id, (err, doc) => { if (!err) { res.render('student/addOrEdit', { viewTitle: 'Update Student', student: doc, }); } });});
Note: For step-20: Updating Record in the application following changes needs to be updated.
list.hbs
<td> <a href="/student/{{this._id}}"><i class="fa fa-pencil fa-lg " aria-hidden="true"></i></a> <a><i class="fa fa-trash fa-lg" aria-hidden="true"></i></a></td>
addOrEdit.hbs <h3>{{viewTitle}}</h3><form method="POST" action="/student" autocomplete="off"> <input type="hidden" name="_id" value="{{student._id}}"> <div class="form-group"> <label>Full Name</label> <input type="text" class="form-control" name="fullName" placeholder="Full Name" value="{{student.fullName}}"> <div class="form-group"> <label>Email</label> <input type="text" class="form-control" name="email" placeholder="Email" value="{{student.email}}"> <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="{{student.mobile}}"> </div> <div class="form-group col-md-6"> <label>City</label> <input type="text" class="form-control" name="city" placeholder="City" value="{{student.city}}"> </div> </div> <div class="form-group"> <button type="submit" class="btn btn-info"><i class="fa fa-database"></i> Submit</button> <a class="btn btn-secondary" href="/student/list"><i class="fa fa-list-alt"></i> View All</a> </div></form>
studentController.js: Now we need to also update the following changes in this file also in order to save the updated record.
Important: Replace the previous post request with the following code
router.post('/', (req, res) => { if (req.body._id == '') insertRecord(req, res); else updateRecord(req, res);});
function updateRecord(req, res) { Student.findOneAndUpdate( { _id: req.body._id }, req.body, { new: true }, (err, doc) => { if (!err) { res.redirect('student/list'); } else { console.log('Error during record update : ' + err); } } );}
Output in Browser- http://localhost:3000/student/list
Step-21: Now we create a new route in studentController.js for Delete Button to delete the previously stored record.
studentController.js
router.get('/delete/:id', (req, res) => { Student.findByIdAndRemove(req.params.id, (err, doc) => { if (!err) { res.redirect('/student/list'); } else { console.log('Error in student delete :' + err); } });});
Step-10: Now update server.js for Configuring Express Handlebars.
server.js
studentController.js
server.js
studentController.js
router.post('/', (req, res) => {
Output in Browser- http://localhost:3000/student : Insert your student Data in the Form and press Submit Button, You will be redirected to /student/list display the sample ouput as Student List (This view will be update in the next session). At the same time, data will also be stored in the MongoDB.
Step-16: Now update in studentController.js for reading the list of student's records from MongoDb database







