CRUD application using AngularJs, NodeJs, MongoDB

This  explains how we can implement a Web application built using angularjs, node js to perform create, read, update and delete operations on MongoDB database.

Web Application Architecture

The following diagram gives an overall view of our application and illustrates the various exchange between modules.


Prerequist

To better understand the next chapters, we will do a brief reminder about thinks that you should know :

1) AngularJs 

AngularJS is a structural framework for dynamic web apps.

2) NodeJs

NodeJs is very powerful javascript-based framework/plateform built on Google Chrome's Javascript V8 Engine. It is used to develop I/O intensive web applications like video streaming sites, single-page applications, and other web applications.
NodeJs is a server application, is was developed by Ryan Dahl in 2009.

Environnement setup

to install NodeJs in your machine, you should download it first from nodeJs Web Site.
to make sure every think that run succeffully :
a) open your nodejs command prompt :


b) write some code :


Examples

the below examples, will help you to good understand the  next chapter in wich we talk about the implementation of the server side using nodejs.
a) Create Hello world
  • create a helloworld.js file on your machine and write this code :

console.log("Hello wordl !");

  • run it using node.js command prompt


b) Create Server
  • create a js file named server.js

 //Import required module 
 var http = require("http");
 //create local server that listen on 8081 port 
 http.createServer(function (request, response) {
   // Send the HTTP header 
   // HTTP Status: 200 : OK
   // Content Type: text/plain
   response.writeHead(200, {'Content-Type': 'text/plain'});
   // Send the response body as "Hello World"
   response.end('Hello World\n');
}).listen(8081);
// Console will print the message
console.log('Server running at http://127.0.0.1:8081/');

  • run it using node command prompt


  • Make a request to nodejs server
open http://127.0.0.1:8081/ on any browser and you will get the bellow result :

c) Installing modules using npm :
  • What is NPM (Node Package Manager)?
npm is bundled with Node.js installables. and its a very useful tool to provides command line utility to install nodejs modules.
  • command line
npm install <Module Name>

d) Create a restfull  web services :
  • What is REST architecture ?
REST is web standards based architecture and uses HTTP Protocol. that allow client to access to resource in server side for modification and reading via HTTP protocol. each ressources is identified by url and global ID.
the representation of a resource returned it can be text, XML or JSON (the popular one).
  • Coding 
1) installaing express module  using npm
npm install express
this command install the famous nodejs web framework module called express.
for more knowledge about the express framework you can visit this link : Express.js official site
2) create a restfull server
//import required module
var express = require('express');
//instantiate
var app = express();
//build our restful service
app.get('/getHWMsg', function (req, res) {
   res.end('Hello World');
});
//start server
var server = app.listen(8081, function () {
  console.log("Server is listening at http://127.0.0.1:8081/")
});    

3) testing request
open the following url :http://127.0.0.1:8081/getHWMsg  in your browser and you will see the bellow result :

 

3) MongoDB

MongoDB is an sgbd oriented documents,  and it does not require a predefined data schema.
MongoDB stores all documents into collections.
the representation of the stored documents is on BSON (Binary json data).
the following diagram defines how data are stored into MongoDB :

 
1) Environnement setup :

  • download MongoDb from this link : MongoDB download
  • Create target MongoDB folder, I created : C:\nodejsExample\mongoDb
  • Create target MongoDB Data folder, I created : C:\nodejsExample\mongoDb\data
  • Add MongoDB bin folder (you can find it in MongoDB installation folder) to the path environment variable
  • create MongoDB configuration file, i created : C:\mongoDb\nodejsExample\mongod.cfg that contains the following lines :

systemLog:
    destination: file
    path: C:\nodejsExample\mongoDb\data\log\mongod.log
storage:
    dbPath: C:\nodejsExample\mongoDb\data\db

  • install the mongodb service :

 
 
the precedent command create a service with a default name : MongoDB.
 
  • run mongodb service by tapping on command line the following command:

<span class="n">net</span> <span class="n">start</span> <span class="n">MongoDB</span>

  • check the log file to view the url of your service, in my case i found : mongodb://localhost:27017/db
  • Think about what development language you plan to use :
in our example we will use nodejs, so we should install mongo driver for nodejs using npm command :
npm install mongodb

To see more about MongoDB, you can follow this link.


Implementation of server side

The server will be an intermediary between client and DataBase, it will accept the HTTP requests sent by client, processes them , and return a Rest response to client (JSON or Text data).

Description of requests can be sent by client

The aim of our application is to ensure the implementation of CRUD operations , and following this logic our services will be developed.
1) getPersons : get all available persons in database .
  • Input parameters :
void
  • Output parameters
Json data composed by a list of persons.
1) addPerson : create a new person in database .
  • Input parameters :
obj : contains the data of new person to add. this argument is in json format.
  • Output parameters
status :  return true, if the insert operation is successfully done, else will return false.

1) updatePerson : create a new person in dataBase .
  • Input parameters :
obj : contains new data of an existing person identified by _id . this argument is in json format.
  • Output parameters
status :  return true, if the update operation is successfully done, else will return false

2) removePerson : remove an existing  person identified by _id from database.
  • Input parameters :
id :  is an integer data that refers to person identifier.
  • Output parameters
status :  return true, if the delete operation is successfully done, else will return false.

 

Server implementation

1) include the requirement modules

var mongodb = require('mongodb');
var MongoClient = require('mongodb').MongoClient;
var assert = require('assert');
var url = 'mongodb://localhost:27017/db';
var express = require('express');
var app = express();
to fix the issue of : No 'Access-Control-Allow-Origin', i add the following middleware to my  NodeJS/Express app :
app.use(function(req, res, next) {
        res.header("Access-Control-Allow-Origin", "*");
        res.header("Access-Control-Allow-Headers", "X-Requested-With");
        res.header("Access-Control-Allow-Headers", "Content-Type");
        res.header("Access-Control-Allow-Methods", "PUT, GET, POST, DELETE, OPTIONS");
        next();
 });
var server = require('http').createServer(app);
var io = require('C:\\Users\\onasri\\AppData\\Roaming\\npm\\node_modules\\socket.io')(server);
io = io.listen(server, {log:false, origins:'*:*'});

2) implement crud methods by using Mongodb client :

//insert a new person 
 var insertPerson = function(db, obj, callback) {
    db.collection('persons').insertOne(  obj, function(err, result) {
    assert.equal(err, null);
    console.log("Inserted a new person into the persons collection.");
    callback();
    }); 
  };
//get all persons 
 var findPersons = function(db, callback) {
  var cursor = db.collection('persons').find();
     cursor.toArray(function(err, items) {
    console.log(items);
    callback(items);
    });
  };
//update an existing person in persons collection
 var updatePersons = function(db, arg, callback) {
    var  obj = JSON.parse(arg);
    var key =  obj["_id"];
    db.collection('persons').updateOne(
    {"_id": new mongodb.ObjectID(""+key)},
    {
    $set: { "firstname": obj.firstname, "lastname": obj.lastname, 
    "adress":{"zipcode":  obj.adress.zipcode, "country": obj.adress.country}}
    }, function(err, results) {
     console.log(results);
     callback();
    }); 
 };
//remove existing person from persons collection
 var removePersons = function(db, key, callback) {
      db.collection('persons').deleteMany(
    { "_id": new mongodb.ObjectID(key)},
     function(err, results) {
     console.log(results);
     callback();
    }
    );
 };

3) implement a rest services

//RESTFUL methods  
 app.get('/getPersons', function (req, res) {   
    MongoClient.connect(url, function(err, db) {
     assert.equal(null, err);
     findPersons(db, function(data){ db.close(); res.end(JSON.stringify(data)); });
   }); 
  
 });   
 app.get('/addPerson', function (req, res) {   
    MongoClient.connect(url, function(err, db) {
    //to process other instructions we check if err != null
     assert.equal(null, err);
     //get parameter from url request
     var obj = req.query.obj;
      insertPerson(db, JSON.parse(obj), function(){
      db.close();
      res.end("true");
     }); 
   }); 
 });
 app.get('/updatePerson', function (req, res) { 
   
   MongoClient.connect(url, function(err, db) {
     //to process other instructions we check if err != null
     assert.equal(null, err);
     //get parameter from url request
     var obj = req.query.obj; 
      updatePersons(db, obj, function(){
      db.close();
      res.end("true");
     }); 
   });
 });
 app.get('/removePerson', function (req, res) {    
   MongoClient.connect(url, function(err, db) {
     //to process other instructions we check if no error occurred
     assert.equal(null, err);
     //get id parameter from url request
    var key = req.query.id;
        removePersons(db, key, function(){
      db.close();
      res.end("true");
     }); 
   });
 });
4) Extra code
the below code allow to extract from a json file a list of person to populate your database.
  • person.json file :

[
 {"firstname":"Nasri 0","lastname":"Omar 1","adress":{"zipcode":1,"country":"France"}},
 {"firstname":"Nasri 1","lastname":"Omar 2","adress":{"zipcode":2,"country":"France"}},
 {"firstname":"Nasri 2","lastname":"Omar 3","adress":{"zipcode":3,"country":"France"}}
]
  • parsing and populate the database using an existing data
var fs = require("fs");
 //populate the dataBase in first time
   fs.readFile( "persons.json", 'utf8', function (err, data) {
       persons = JSON.parse( data );
    MongoClient.connect(url, function(err, db) {
     assert.equal(null, err);
     //purge the database by removing all document
     db.collection('persons').remove({})
     db.collection('persons').drop();
     //create a new collection and insert data
     db.collection('persons').insert( persons, function(err, result) {
     console.log( result );
      assert.equal(err, null);
     console.log("Inserted many documents into persons collection.");
      db.close();
     }); 
   });  
   });
5) create our server

//create our server that listening at 127.0.0.1:8081
server.listen(8081, function () {
  var host = server.address().address
  var port = server.address().port
  console.log("Example app listening at http://%s:%s", host, port)
});

6) start server
open nodejs command prompt and write the following code :
node CRUDnode.js

implementation of client side

I) Project tree

the client project tree is constituted by three parts :
1) Controllers folder : contains the declaration of controllers.
2) Services folder  : has the declaration of custom services related to each controllers.
2) View : contains html pages and a js file that contains the initialization of different module and routes.
the following picture,  can more explain the organisation of our project  :

 

II) Services

Each service created, contains a list of functions that build a request (http) which point to a specific url in server side.
these services will be called from controller to execute some specific actions.
1) IndexServices.js
return functions that build a http request :
  • getPersons : return http request that point to :  http://127.0.0.1:8081/getPersons.
  • addPerson : return http request that point to : http://127.0.0.1:8081/addPerson.
  • editPerson : return http request that point to : http://127.0.0.1:8081/updatePerson.
  • deletePerson : return http request that point to : http://127.0.0.1:8081/removePerson.

appIndex.factory('DataService', ['$http', function ($http) {

    var getPersons = function () {
        return $http.get("http://127.0.0.1:8081/getPersons");
    }
    var addPerson = function (obj) {
        var data = angular.copy(obj);
        
        var parameters = {
            obj: JSON.stringify(data),
        };
        var config = {
            params: parameters
        };
        return $http.get("http://127.0.0.1:8081/addPerson", config);
    }    
    var editPerson = function (obj) {
        //removed the $$hashKey properties
        var data = angular.copy(obj);
        var parameters = {
            obj: JSON.stringify(data),
        };
        var config = {
            params: parameters
        };
        return $http.get("http://127.0.0.1:8081/updatePerson", config);
    }
    var deletePerson = function (id) {
        var parameters = {
            id: id,
        };
        var config = {
            params: parameters
        };
        return $http.get("http://127.0.0.1:8081/removePerson", config);
    }
    
    return {
        getPersons: getPersons,
        addPerson: addPerson,
        editPerson: editPerson,
        deletePerson: deletePerson,
    }
}]);   

III) Controller

the aim functionalities of this controller are :
  • load persons from remote database 
  • remove an existing person identified by _id
  • create a new person
  • update an existing person using its identifier _id

appIndex.controller('indexController', ['$scope', 'DataService', function ($scope, DataService) {
    $scope.listPerson = "";
    //load all available person from server.
    loadPersons();
    function loadPersons()
    {
        DataService.getPersons().then(function successCallback(response) {
            if (response.data.length > 0) {
                $scope.listPerson = response.data;
            } 
        }, function errorCallback(response) {
            //alert(response.status);
        });
    }
  
    $scope.Remove = function(id) {
        DataService.deletePerson(id).then(function successCallback(response) {
            if (response.data == "true") {
                loadPersons();
                alert("succefully done !");
            }
        }, function errorCallback(response) {
            //alert(response.status);
        });  
    }
    
    $scope.Edit = function (elem) {
        DataService.editPerson(elem).then(function successCallback(response) {
              if (response.data == "true") {
                loadPersons();
                alert("succefully done !");
            }
        }, function errorCallback(response) {
            //alert(response.status);
        });
    }
    $scope.AddNewPerson = function (master) {
        DataService.addPerson(master).then(function successCallback(response) {
            //refresh List of person
            loadPersons();
            //hide modal : 
            $("#myModalFormAddPerson").modal("hide");
        }, function errorCallback(response) {
            alert(response.status);
        }); 
    }
}]);

IV) View

  • index.html

>!DOCTYPE html>
>html>
>head>
>meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    >title>NASRI OMAR CRUD Application>/title>
 >meta charset="utf-8" />
    >script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js">>/script>
    >link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
    >script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js">>/script>
    >script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js">>/script>
    >script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js">>/script>
    >script src="ApplicationCRUD.js">>/script>
    >script src="Services/IndexServices.js">>/script>
    >script src="Controllers/indexCtrl.js">>/script>
>/head>
>body ng-app="MyAppCrud" ng-controller="indexController">
    >div id="wrapper">

        >div class="modal  fade"  id="myModalFormAddPerson" role="dialog">
            >div class="modal-dialog">
                >div class="modal-content">
                    >div class="modal-header">
                        >button type="button" class="close" data-dismiss="modal" aria-label="Close">>span aria-hidden="true">&times;>/span>>/button>
                        >h4 class="modal-title" id="IdModalTitle"> Add New Person>/h4>
                    >/div>
                    >div class="modal-body">
                        >!--Formulaire-->
                        >form name="myform"  class="form-horizontal">
                            >div class="form-group">
                                >label class="col-sm-4 control-label" required>first Name>/label>
                                >div class="col-sm-8">
                                    >input type="text" ng-model="master.firstname" class="form-control" placeholder="enter first Name" ng-required="true" />
                                >/div>
                            >/div>
                            >div class="form-group">
                                >label class="col-sm-4 control-label">last Name>/label>
                                >div class="col-sm-8">
                                    >input type="text" ng-model="master.lastname" class="form-control" placeholder="enter last Name" ng-required="true" />
                                >/div>
                            >/div>
                            >div class="form-group">
                                >label class="col-sm-4 control-label">Zip code>/label>
                                >div class="col-sm-8">
                                    >input type="text" ng-model="master.adress.zipcode" class="form-control" placeholder="enter zip code" ng-required="true" />
                                >/div>
                            >/div>
                            >div class="form-group">
                                >label class="col-sm-4 control-label">country>/label>
                                >div class="col-sm-8">
                                    >input type="text" ng-model="master.adress.country" class="form-control" placeholder="enter country" ng-required="true" />
                                >/div>
                            >/div>
                            >div class="modal-footer">
                                >button class="btn btn-default" data-dismiss="modal">Cancel>/button>
                                >button ng-click="myform.$valid && AddNewPerson(master)" class="btn btn-primary">Validate>/button>
                            >/div>
                        >/form>
                    >/div>
                >/div>
            >/div>
        >/div>
        >div class="row">
            >center>>h3>Sample CRUD application using AngularJS, NodeJs and MongoDb>/h3>>/center>
        >/div>
        >div class="row">
            >div class="col-lg-8 col-lg-offset-2">
                >div class="row">
                    >button type="button" class="btn btn-info btn-sm" data-toggle="modal" data-target="#myModalFormAddPerson">Add Person>/button>
                >/div>
                >div class="row">
                    >table class="table table-responsive">
                        >thead>
                            >tr>>th>First Name>/th>>th>Last Name>/th>>th>Address>/th>>/tr>
                        >/thead>
                        >tbody ng-repeat="elem in listPerson">
                            >tr>
                                >td  class="col-lg-2">>input type="text" ng-model="elem.firstname" />>/td>
                                >td class="col-lg-2">>input type="text" ng-model="elem.lastname"  />>/td>
                                >td class="col-lg-6">Zip code : >input type="text" ng-model="elem.adress.zipcode" />  Country : >input type="text" ng-model="elem.adress.country" />>/td>
                                >td class="col-lg-2">>a href="#" ng-click="Edit(elem)">>span class="glyphicon glyphicon-edit">>/span> save>/a>   >a href="#" ng-click="Remove(elem._id)">>span class="glyphicon glyphicon-remove">>/span> Remove>/a> >/td>
                            >/tr>
                        >/tbody>
                    >/table>
                >/div>
            >/div>
            >div class="col-lg-offset-2">>/div>
        >/div>
    >/div>
>/body>
>/html>

V) User interface manipulation

1) Load available Persons


2) Add new Person
First, user should click on add Person button to show insertion form.

after complete form, clic on validate button to add a new person.


3) Update an existing person
user can change the attributes of a selected person and clic on associate save icon , to save changes.


4) Remove a selected person
user can select a person to delete it, and clic on remove icon  :


result :



 

12 comments:

  1. I have read your blog its very attractive and impressive. I like it your blog.
    Angularjs Development Company

    ReplyDelete
  2. Thanks for giving such information, I read many blogs but did not get such information. I have also written something about Benefits Of Node.Js For Startups, must read it once Advantages Of Node.Js For Startups In 2022

    ReplyDelete
  3. https://thingoftheday.blogspot.com/2016/01/crud-application-using-angularjs-nodejs.html?sc=1653562779563#c1271807046703417404

    ReplyDelete
  4. Thanks for giving such information but in my list also India's best development company Top Development company in India

    ReplyDelete
  5. Thanks for giving such full information, not everyone has such information, I have also written something, that must read Custom Web Solution Development

    ReplyDelete
  6. Thanks for giving such great information, I have kept you a follower because your information is different. Hire outsourcing node.js developer

    ReplyDelete
  7. I read many blogs but hardly got information like yours. thanks for giving information about Outsource node js developer in India

    ReplyDelete
  8. I read many blogs but hardly got information like yours. thanks for giving information about Hire outsourcing node.js developer

    ReplyDelete

Genuine websites to earn money.

If you are interested in PTC sites then this article is for you. I have personally tried many of the sites and found that the best thing ...