Node MongoDB CRUD Operation tutorial

Simple Node MongoDB CRUD Operation tutorial

In this tutorial, you will learn how to perform crud operation with Node JS and MongoDB.

If you want to see a demo of this CRUD application then watch this video.


Follow the below steps to create Node MongoDB CRUD application


Step – 1

First, you need to install NodeJS and MongoDB on your Computer.

To make this tutorial I used MongoDB community server. But you can use MongoDB atlas or MLab also.

After that create a new folder on your desktop and name it as you wish.

Now initialize npm inside the newly created folder. After initializing npm you have to install some node dependency –

  • Express JS. (npm install express --save)
  • Twig template engine. (npm install twig --save)
  • Body Parser. (npm install body-parser --save)
  • MongoDB. (npm install mongodb --save)

My package.json file

{
  "name": "node_mongo",
  "version": "1.0.0",
  "description": "CRUD With NodeJS + MongoDB",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Webtutorials.ME",
  "license": "MIT",
  "dependencies": {
    "body-parser": "^1.18.3",
    "express": "^4.16.4",
    "mongodb": "^3.1.13",
    "twig": "^1.13.2"
  }
}

Step – 2

In this step, on your MongoDB create a new database called mongo_crud.

After that inside mongo_crud database creates a new collection called posts.


Step – 3

After completing the database setup now time to creating our files.

Before we start to our creating files let’s take a look at the structure of our application folder.

folder structure of the crud application

Files creation

First we will create index.js file.

index.js

const express = require('express');
const mongodDB = require('mongodb');
const MongoClient = mongodDB.MongoClient;
const app = express();
const twig = require('twig');
const bodyParser = require('body-parser');
// MONGODB URL
const db_url = "mongodb://localhost:27017/";

// VARIABLE DECLARED 
let dbConnection;
let post_id;
let isValid_obj_id;

// USE BODY-PARSER MIDDLEWARE
app.use(bodyParser.urlencoded({extended:false}));

// SET OUR VIEW ENGINE AND VIEWS
app.set('view engine', 'html');
app.engine('html', twig.__express);
app.set('views','views');

// HOME PAGE
app.get('/', (req, res) => {
    // GET ALL POSTS FORM DATABASE
    dbConnection.collection("posts").find().sort({insert_date:-1}).toArray((err, posts) => {
        if (err) throw err;
        res.render('home',{
            posts:posts
        });
    }); 
});

// INSERT POST
app.post('/', (req, res) => {
    dbConnection.collection('posts').insertOne({...req.body,insert_date:new Date()}).then(result => {
        res.redirect('/');
    }).catch(err => {
        console.log(err);
        res.redirect('/');
    });
});

// EDIT POST
app.get('/edit/:id', (req, res) => {
    post_id = req.params.id;
    isValid_obj_id = mongodDB.ObjectID.isValid(post_id);
    // CHECK IS OBJECT ID VALID ?
    if(isValid_obj_id === false){
        // IF INVALID OBJ ID
        res.redirect('/');
    }
    else{
        // GET POST BY ID
        dbConnection.collection("posts").findOne({_id:mongodDB.ObjectID(post_id)},(err,post) => {
            if (err) throw err;
            if(!post){
                res.redirect('/');
            }
            else{
                // RENDER EDIT VIEW WITH POST DATA
                res.render('edit',{
                    post:post
                });
            }    
        });
    }   
});

// UPDATE POST
app.post('/edit/:id', (req,res) => {
    post_id = req.params.id;
    // UPDATE POST BY ID 
    dbConnection.collection("posts").updateOne({_id:mongodDB.ObjectID(post_id)}, {$set:req.body}, (err, result) => {
        if (err) throw err;
        res.redirect('/');

    });
});

// DELETE POST
app.get('/delete/:id', (req, res) => {
    isValid_obj_id = mongodDB.ObjectID.isValid(req.params.id);
    if(isValid_obj_id === false){
        res.redirect('/');
    }
    else{
        // DELETE POST BY ID
        dbConnection.collection("posts").deleteOne({_id:mongodDB.ObjectID(req.params.id)},(err, deletePost) => {
            if (err) throw err;
            res.redirect('/');
        });
    }
});

// MAKE DATABASE CONNECTION
MongoClient.connect(db_url, {useNewUrlParser: true}, (err, db) => {
    if (err) throw err;
    // SET DATABASE
    dbConnection = db.db('mongo_crud');
    // Run our app if the database is successfully connected.
    app.listen(3000);
});

After creating the index.js file, now time to make our views, for that create a new folder on our application folder and name it views.

Inside the views folder, we will create two views one is home.html for the home page and another is edit.html for edit post page.

home.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>CRUD WITH MONGODB - Webtutorials.ME</title>
    <style>
        *{
            box-sizing: border-box;
            -webkit-box-sizing: border-box;
        }
        body{
            margin: 0;
            padding: 20px;
            background-color: #f7f7f7;
            font-family: sans-serif;
        }
        h1{
            text-align: center;
            color: #000000;
        }
        h1 span{
            color: #2ecc71;
        }
        hr{
            border-color: #ffffff;
        }
        .post-container,.form-container{
            max-width: 600px;
            padding: 10px;
            margin: 0 auto;
            background-color: #ffffff;
            border: 1px solid rgba(0, 0, 0, .1);
        }
        .form-container label{
            font-weight: bold;
            color: #000000;
        }
        .input_style{
            width: 100%;
            padding: 10px;
            background: #ffffff;
            border: 1px solid rgba(0, 0, 0, .2);
            outline: none;
            border-radius: 2px;
            font-family: sans-serif;
            font-size: 16px;
            resize: vertical;
        }
        .submit-btn{
            margin: 10px 0;
            padding: 10px 20px;
            text-transform: uppercase;
            font-size: 14px;
            cursor: pointer;
            background: #ee4c58;
            border: 1px solid rgba(0, 0, 0, .1);
            color: #FFF;
        }
        .submit-btn:hover{
            background-color: #232323;
            color: #ffffff;
        }


        .post-container ul{
            padding: 0;
            margin: 5px 0;
            list-style: none;
            border-bottom: 1px solid #dddddd;
        }
        .post-container ul h3, .post-container ul p{
            padding: 0;
            margin: 0;
        }
        .post-container ul p{
            color: #444444;
        }
        .post-container ul .edit-btn{
            display: inline-block;
            padding: 5px;
            border: 1px solid rgba(0, 0, 0, .1);
            margin: 5px 0;
            color: #ffffff;
            background-color: #11862f;
            text-decoration: none;
        }
        .post-container ul .delete-btn{
            display: inline-block;
            padding: 5px;
            border: 1px solid rgba(0, 0, 0, .1);
            margin: 5px 0;
            color: #ffffff;
            background-color: #ff4c4c;
            text-decoration: none; 
        }
        .date_author{
            font-size: 14px;
            color: #555;
            font-style: italic;
        }
    </style>
</head>
<body>
    <div class="main-container">
        <div class="form-container">
            <h1><span>Webtutorials</span>.ME</h1>
            <!-- INSERT POST FORM -->
            <form action="" method="POST">
                <label for="title">Title</label>
                <input type="text" class="input_style" name="title" id="title" placeholder="Enter post title" required>
                <label for="content">Content</label>
                <textarea name="content" id="content" class="input_style" placeholder="Write here" required></textarea>
                <label for="author">Author Name</label>
                <input type="text" id="author" name="author_name" class="input_style" placeholder="Author Name">
                <input type="submit" value="Post" class="submit-btn">
            </form>
        </div>
        <br>
        <div class="post-container">
            <!-- SHOW ALL POSTS -->
            {%if posts%}
                {% for post in posts %}
                    <ul>
                        <li>
                            <h3 class="post-title">{{ post.title|e }}</h3>
                            <span class="date_author">{{post.insert_date|date("M d, Y")}} | By, {{post.author_name|e}}</span>
                            <p class="post-content">{{ post.content|e }}</p>
                            <span class="post-action">
                                <a href="/edit/{{ post._id}}" class="edit-btn">Edit</a>
                                <a href="/delete/{{ post._id}}" class="delete-btn">Delete</a>
                            </span>
                        </li>
                    </ul>
                {% endfor %}
            {%else%}
            <h4>Oops empty!</h4>
            <p>Write some posts</p>
            {%endif%}
        </div>
    </div>
</body>
</html>

edit.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>CRUD WITH MONGODB - Webtutorials.ME</title>
    <style>
        *{
            box-sizing: border-box;
            -webkit-box-sizing: border-box;
        }
        body{
            margin: 0;
            padding: 20px;
            background-color: #f7f7f7;
            font-family: sans-serif;
        }
        h1{
            text-align: center;
            color: #000000;
        }
        h1 span{
            color: #2ecc71;
        }
        hr{
            border-color: #ffffff;
        }
        .post-container,.form-container{
            max-width: 600px;
            padding: 10px;
            margin: 0 auto;
            background-color: #ffffff;
            border: 1px solid rgba(0, 0, 0, .1);
        }
        .form-container label{
            font-weight: bold;
            color: #000000;
        }
        .input_style{
            width: 100%;
            padding: 10px;
            background: #ffffff;
            border: 1px solid rgba(0, 0, 0, .2);
            outline: none;
            border-radius: 2px;
            font-family: sans-serif;
            font-size: 16px;
            resize: vertical;
        }
        .submit-btn{
            margin: 10px 0;
            padding: 10px 20px;
            text-transform: uppercase;
            font-size: 14px;
            cursor: pointer;
            background: #ee4c58;
            border: 1px solid rgba(0, 0, 0, .1);
            color: #FFF;
        }
        .submit-btn:hover{
            background-color: #232323;
            color: #ffffff;
        }
    </style>
</head>
<body>
    <div class="main-container">
        <div class="form-container">
            <h1><span>Webtutorials</span>.ME</h1>
            <!-- EDIT POST FORM -->
            <form action="" method="POST">
                <label for="title">Title</label>
                <input type="text" class="input_style" name="title" id="title" placeholder="Enter post title" value="{{post.title|e}}" required>
                <label for="content">Content</label>
                <textarea name="content" id="content" class="input_style" placeholder="Write here" required>{{post.content|e}}</textarea>
                <label for="author">Author Name</label>
                <input type="text" value="{{post.author_name|e}}" id="author" name="author_name" class="input_style" placeholder="Author Name">
                <input type="submit" value="Update" class="submit-btn">
                <a href="/">Home</a>
            </form>
        </div>
    </div>
</body>
</html>

Completed!

Download this project from GitHub –


Learn also:

CRUD with Node JS and MongoDB

Leave a Reply

Your email address will not be published. Required fields are marked *