Node MongoDB CRUD Operation tutorial

Crud with nodejs and mongodb

Simple Node MongoDB CRUD Operation tutorial

In this tutorial you will learn how to perform crud operation with node mongodb.

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


To create Node MongoDB CRUD application follow the below steps.

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 create 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.

node mongodb folder structure

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!

Posts Navigation


Leave a Reply

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