Node.js Express MongoDB Tutorial

Express is a Node.js web application framework that provides a robust set of features to develop rich web applications. Today we are going to deep dive in Node.js Express MongoDB Tutorial. If you want to know what is Node.js and why we use in server side technology, then please read my article Why we use Node js as a server side technology

Node.js Express MongoDB Tutorial will use the NoSQL database like MongoDB to store the form values in the database, Express as the Web framework and Node.js as a platform. We will use NPM as a package manager for our dependencies and Git for version control for our code. 

Note: If you do not have a Node.js install, then please go to Node.js official website and download the package according to your OS.

Step: 1

Create a project folder and go to that directory and put the following command in your terminal.

npm init

After answering all the data, in your root folder package.json file will be created. This file is a config file for our dependencies, so when we download new packages from Node Package Manager, package.json file will be automatically updated.

Step: 2

Get the Express package from Node Package Manager by typing following command on terminal

npm install --save express

Possible Error Info: npm WARN install Refusing to install express as a dependency of itself

If you find above error during installation, make sure your project name must not contain “express” word.

Step: 3

Create a file in root called “app.js.” This file is our main server file in which it bootstraps the node server, and also it serves some static files. Put the following code in it.

// app.js

var express = require('express');
var app = express();
var port = 3000;
app.listen(port, function(){
  console.log('hello world');
})




Now go to the terminal, and if you type node app, you will get hello world in a console.

If we do not want to restart the server manually then we can use one package called nodemon. It is kind of server that reloads every time we change the file.

npm install -g nodemon

Change the package.json file and add the following line in “scripts” object.

"start": "nodemon app.js"

When you type in terminal “npm start”, it will bootstrap the server and when we change the files, it will automatically restart.

Step: 4

If we want to set up a routing in our express app, then type following in it.

// app.js


var express = require('express');
var app = express();
var port = 3000;
app.listen(port, function(){
  console.log('Server is running on port:', port);
})
app.get('/', function(req, res){
    res.send('Hello Express');
});

Restart the server. Switch to the chrome and hit: http://localhost:3000  We get “Hello Express” in the browser.

Step: 5

First, create a directory in the root folder called “public.” Download bootstrap framework and move CSS and Javascript files to the public directory.

Also, create views directory in the root folder and then in future, we will put our whole HTML files.

For serving static files from our server, put the below code in the app.js file.

// app.js

app.use(express.static('public'));

Go to http://localhost:3000/css/bootstrap.css  If CSS code is showing up in the browser, then we are on right way.

So, our whole app.js file will look like this.

// app.js

var express = require('express');
var app = express();
var port = 3000;

app.use(express.static('public'));

app.listen(port, function(){
  console.log('Server is running on port:', port);
})
app.get('/', function(req, res){
    res.send('Hello Express');
});

Step: 6

Here we are going to use “ejs” as a templating engine, so first, we need to download that through NPM

npm install --save ejs

Now we need to update our app.js file to set the view engine.

// app.js

app.set('view engine', 'ejs');

Create one view file in views >> index.ejs and put the following code in it.

<!-- index.ejs -->

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>EJS Engine</title>
    <link rel="stylesheet" href="/css/bootstrap.min.css">
  </head>
  <body>
    <div class="container">
      <div class="jumbotron">
        Node JS Express Tutorial
      </div>
    </div>
  </body>
</html>

Step: 7

Set up routes for our application. So first we need to use Router module provided by Express

// app.js

var itemRouter = express.Router();

Now we can create as many routes as we want.

Here we have defined itemRouter, so we can create routes from that, so we are creating following routes from the itemRouter module.

// app.js

var itemRouter = express.Router();

app.use('/items', itemRouter);

itemRouter.route('/').get(function (req, res) {
  res.render('items');
});

itemRouter.route('/single').get(function (req, res) {
  res.render('singleItem');
});

So, when we hit the URL like http://localhost:3000/items, the express will render the items.ejs view.

Now, we need to create items.ejs view and put just one line to check whether if it is running or not.

<!-- items.ejs -->

Node.js Express Tutorial

If you will see in the browser, Node.js Express MongoDB Tutorial will be there. Now, create another view like singleItem.ejs in views folder and then put in that just Single Route. If you hit the URL like http://localhost:3000/items/single, then also we can see Single Route in our browser. So, first, we define our root router like /items and then from that we can give some another route from that route, so that way route handling is very easy in Node Express Tutorial application.

Step: 8

We are going to separate our routes code from our app.js files. So, create routes folder in the src folder and in routes folder create a file called itemRoutes.js. Our path will look like src >> routes >> itemRoutes.js. Put the following code in it.

// itemRoutes.js

var express = require('express');
var app = express();
var itemRouter = express.Router();

itemRouter.route('/').get(function (req, res) {
  res.render('items');
});

itemRouter.route('/single').get(function (req, res) {
  res.render('singleItem');
});

module.exports = itemRouter;




Here, we have exports itemRouter module so that app.js can include this router module and our application will not crash.

Now in app.js file, we need to require this file so that our code won’t break. Our app.js file will look like this.

// app.js

var express = require('express');

var app = express();
var port = 3000;

var itemRouter = require('./src/routes/itemRoutes');

app.set('view engine', 'ejs');
app.use(express.static('public'));
app.use('/items', itemRouter);

app.listen(port, function () {
  console.log('Server is running on port:', port);
});

app.get('/', function (req, res) {
  res.render('index');
});

In above code, we have required the itemRouter module and then use it in our application.

Step: 9

Now, we need to create add item page, so in views folder, create one ejs file called addItem.ejs

<!-- addItem.ejs -->

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>EJS Engine</title>
    <link rel="stylesheet" href="/css/bootstrap.min.css">
  </head>
  <body>
    <div class="container">
        <h1>Add Item</h1>
        <form method="post" action="/add/post">
          <div class="form-group">
            <label for="item">Item</label>
            <input type="text" class="form-control" id="item" name="item">
          </div>
          <button type="submit" class="btn btn-default">Add</button>
        </form>
    </div>
  </body>
</html>

Next step is to register this route in itemRoutes.js file, so put the following code in it.

Read More
1 of 2
// itemRoutes.js

itemRouter.route('/add').get(function (req, res) {
  res.render('addItem');
});

Switch to your browser and type http://localhost:3000/items/add

You will see one form, from which we can add new items.

Step: 10

We need to setup a MongoDB database, so first we need to download a package called Mongoose in our application.

npm install --save mongoose

Require this package in our application by the following code.

// app.js

var mongoose = require('mongoose');

Connect our application with the Mongo database.

// app.js

mongoose.Promise = require('bluebird');
mongoose.connect('mongodb://<uname>:<password>@ds139322.mlab.com:39322/aufinancex')
    .then(() => { // if all is ok we will be here
      console.log('Connected');
    })
    .catch(err => { // if error we will be here
        console.error('App starting error:', err.stack);
        process.exit(1);
    });

Here, I have used MongoLab.  MongoLab’s MongoDB hosting platform is the fastest growing cloud Database-as-a-Service in the world. I am using sandbox account, which provides us 500MB data storage. Sign up and create a database and user as well.

They provide you one URI, which you have to connect via Mongoose API and then you are ready to go. I have created database called ‘aufinancex

Step: 11

If we want to send the post request to the server then we need to add one express middleware, which parses our data to json and we can get easily our request on the server side.

npm install --save body-parser

Include this body-parser in our main application file.

// app.js

var bodyParser = require('body-parser');

app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());

Step: 12

Now, create a  post route in the itemRoutes.js, put the following code in it.

// itemRoutes.js

itemRouter.route('/add/post').post(function (req, res) {
  var item = new Item(req.body);
      item.save()
    .then(item => {
    res.redirect('/');
    })
    .catch(err => {
    res.status(400).send("unable to save to database");
    });
});

Here, I have used Item model, which is not created yet, so let’s do it. Create a directory in src folder called models and go in then and create one file called Item.js  So, your directory structure will look like this. src >> models >> Item.js

// Item.js

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var Item = new Schema({
  item: {
    type: String
  },

},{
	collection: 'items'
});

module.exports = mongoose.model('Item', Item);

In Item.js, I have defined Schema in which what fields are using that collection are defined. In our above example, I have just used an item, so define item object and also define collection name. At last export the Item model.

Step: 13

// itemRoutes.js

var Item = require('../models/Item');

itemRouter.route('/add/post').post(function (req, res) {
  var item = new Item(req.body);
      item.save()
    .then(item => {
    res.redirect('/');
    })
    .catch(err => {
    res.status(400).send("unable to save to database");
    });
});

In this file, we have required that model and then use it to save the data.

We have passed the request got from form to the Item model’s constructor and then call save method on it. It will return a Promise, in our case, we are using bluebird library. If it resolves then we got redirect back to the index page and if fail then throw an error.

Step: 14

Now, we need to get the data from the database, so you just need to put following code in the itemRoutes.js file

// itemRoutes.js

itemRouter.route('/').get(function (req, res) {
  Item.find(function (err, itms){
    if(err){
      console.log(err);
    }
    else {
      res.render('items', {itms: itms});
    }
  });
});

Also, we need to modify that item.ejs view to show the data.

<!-- items.ejs -->

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>EJS Engine</title>
    <link rel="stylesheet" href="/css/bootstrap.min.css">
  </head>
  <body>
    <div class="container">
      <table class="table table-striped">
        <thead>
          <tr>
            <td><b>Item Name</b></td>
            <td colspan="2"><b>Action</b></td>
          </tr>
        </thead>
        <tbody>
          <% for(var i=0; i < itms.length; i++) { %>
          <tr>
            <td><%= itms[i].item %></td>
            <td><a href="" class="btn btn-primary">Edit</a></td>
            <td><a href="" class="btn btn-danger">Delete</a></td>
          </tr>
          <% } %>
        </tbody>
      </table>
    </div>
  </body>
</html>

 

Node js Express Tutorial

Step: 15

Create an edit route and edit view.

// itemRoutes.js

itemRouter.route('/edit/:id').get(function (req, res) {
  var id = req.params.id;
  Item.findById(id, function (err, item){
      res.render('editItem', {item: item});
  });
});

Create editItem.ejs file in the views directory

<!-- editItem.ejs -->

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>EJS Engine</title>
    <link rel="stylesheet" href="/css/bootstrap.min.css">
  </head>
  <body>
    <div class="container">
        <h1>Add Item</h1>
        <form method="post" action="/items/update/post">
          <div class="form-group">
            <label for="item">Item</label>
            <input type="text" class="form-control" id="item" name="item" value="<%= item.item %>">
          </div>
          <button type="submit" class="btn btn-default">Update</button>
        </form>
    </div>
  </body>
</html>

Also, update the index view to update edit link route

<!-- items.ejs -->

<td><a href="/items/edit/<%= itms[i]._id %>" class="btn btn-primary">Edit</a></td>

Step: 16

Change the edit form action to update the data

<!-- editItem.ejs -->

<form method="post" action="/items/update/<%= item._id %>">

Register the update route in itemRoutes.js file

// itemRoutes.js

itemRouter.route('/update/:id').post(function (req, res) {
  Item.findById(req.params.id, function(err, item) {
    if (!item)
      return next(new Error('Could not load Document'));
    else {
      // do your updates here
      item.item = req.body.item;

      item.save().then(item => {
          res.redirect('/items');
      })
      .catch(err => {
            res.status(400).send("unable to update the database");
      });
    }
  });
});

So, finally, you can update the item, whichever you want.

Step: 17

Now, remove functionality is remaining, which we will do and then call it a day.

// itemRoutes.js

itemRouter.route('/delete/:id').get(function (req, res) {
  Item.findByIdAndRemove({_id: req.params.id},
	   function(err, item){
		if(err) res.json(err);
		else res.redirect('/items');
	});
});

Also, update the index view to update delete link route.

<!-- items.ejs -->

<td><a href="/items/delete/<%= itms[i]._id %>" class="btn btn-danger">Delete</a></td>

So our some final files will look like this.

// app.js

var express = require('express');
var app = express();
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var port = 3000;

// Mongoose connection with mongodb
mongoose.Promise = require('bluebird');
mongoose.connect('mongodb://<uname>:<password>@ds139322.mlab.com:39322/aufinancex')
    .then(() => { // if all is ok we will be here
      console.log('Start');
    })
    .catch(err => { // if error we will be here
        console.error('App starting error:', err.stack);
        process.exit(1);
    });

// Required application specific custom router module
var itemRouter = require('./src/routes/itemRoutes');

// Use middlewares to set view engine and post json data to the server
app.set('view engine', 'ejs');
app.use(express.static('public'));
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());

app.use('/items', itemRouter);

// Define home route
app.get('/', function (req, res) {
  res.render('index');
});

// Start the server
app.listen(port, function(){
  console.log('Server is running on Port: ',port);
});
// itemRoutes.js

var express = require('express');
var app = express();
var itemRouter = express.Router();

// Require Item model in our routes module
var Item = require('../models/Item');

// Defined Add route
itemRouter.route('/add').get(function (req, res) {
  res.render('addItem');
});

// Defined store route
itemRouter.route('/add/post').post(function (req, res) {
  var item = new Item(req.body);
      item.save()
    .then(item => {
    res.redirect('/items');
    })
    .catch(err => {
    res.status(400).send("unable to save to database");
    });
});

// Defined get data(index or listing) route
itemRouter.route('/').get(function (req, res) {
  Item.find(function (err, itms){
    if(err){
      console.log(err);
    }
    else {
      res.render('items', {itms: itms});
    }
  });
});

// Defined edit route
itemRouter.route('/edit/:id').get(function (req, res) {
  var id = req.params.id;
  Item.findById(id, function (err, item){
      res.render('editItem', {item: item});
  });
});

//  Defined update route
itemRouter.route('/update/:id').post(function (req, res) {
  Item.findById(req.params.id, function(err, item) {
    if (!item)
      return next(new Error('Could not load Document'));
    else {
      // do your updates here
      item.item = req.body.item;

      item.save().then(item => {
          res.redirect('/items');
      })
      .catch(err => {
            res.status(400).send("unable to update the database");
      });
    }
  });
});

// Defined delete | remove | destroy route
itemRouter.route('/delete/:id').get(function (req, res) {
  Item.findByIdAndRemove({_id: req.params.id},
	   function(err, item){
		if(err) res.json(err);
		else res.redirect('/items');
	});
});

module.exports = itemRouter;
// Item.js

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

// Define collection and schema for Items
var Item = new Schema({
  item: {
    type: String
  },

},{
	collection: 'items'
});

module.exports = mongoose.model('Item', Item);

Possible Errors

Please check all the dependency versions of yours with me. Mine package.json file looks like this.

{
  "name": "expapp",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "nodemon app.js"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/KrunalLathiya/node-js-express-tutorial.git"
  },
  "author": "",
  "license": "ISC",
  "bugs": {
    "url": "https://github.com/KrunalLathiya/node-js-express-tutorial/issues"
  },
  "homepage": "https://github.com/KrunalLathiya/node-js-express-tutorial#readme",
  "dependencies": {
    "bluebird": "^3.5.0",
    "body-parser": "^1.17.2",
    "ejs": "^2.5.6",
    "express": "^4.15.3",
    "mongoose": "^4.11.0"
  },
  "devDependencies": {
    "jshint": "^2.9.4",
    "jshint-stylish": "^2.2.1"
  }
}

2) If you have any warning like this,

(node:8996) DeprecationWarning: `open()` is deprecated in mongoose >= 4.11.0, use `openUri()` instead, or set the `useMongoClient` option if using `connect()` or `createConnection()`
Server is running on Port: 3000
Db.prototype.authenticate method will no longer be available in the next major release 3.x as MongoDB 3.6 will only allow auth against users in the admin db and will no longer allow multiple credentials on a socket. Please authenticate using MongoClient.connect with auth credentials.

Possible Solutions

Please connect the database with MongoDB client driver and you can get rid of this warning

For more info, please visit https://expressjs.com/en/guide/database-integration.html

Github Link:

Steps to use this project from GitHub

1) Clone the repo.
2) Go to the project folder and type npm install in terminal
3) Use Mongo lab to create db and user and change the connection URI in app.js file

4)  npm start 
5) Go to the browser and hit http://localhost:3000/items/add

If you have any doubt in this Node js Express Tutorial then ask in a comment below, I am happy to help you out.

You might also like More from author

2 Comments

  1. robit says

    How to setup mongoDB database locally?
    Thanks

  2. mohannad says

    thank you thank you

Leave A Reply

Your email address will not be published.