MEAN Stack

MEAN stack is a single page apps development stack designed for rapid application development of high scaleable applications due to NodeJS’s non-blocking IO design. Applications are designed based on RESTful architecture giving full CRUD capabilities. And it has the advantage of loose coupling to give total separation between API server and AngularJS front-end. API first is a new concept that focuses on building the API interfaces to your services first and then building your UI around the API’s so that it is mobile device responsive.

  • M: MongoDB – A NoSQL database powered by JavaScript.
  • E: ExpressJS – A Node.js application framework.
  • A: AngularJS – A front-end javascript application framework.
  • N: Node.js – A server-side javascript application engine.

 

Getting started

  1. Install NodeJS
  2. In project folder from Git bash command prompt run npm install express
  3. Create server.js in project folder with
    var express = require('express');
    var app = express();
    
    app.get('/', function (re, res) {
      res.send("Hello world from server.js ")
    });
    
    app.listen(3000)
    console.log("Server running on port 3000")

     

  4. Run node server and go to http://localhost:3000 in your brower. You should see the message that it is running.
  5. Next we need to tell Express to find the HTML folder. Add to server.js:
    var express = require('express');
    var app = express();
    
    // Create /public and copy static index.html in
    app.use(express.static(__dirname + "/public"));
    app.use(bodyParser.json())
    
    app.listen(3000)
    console.log("Server running on port 3000")

     

  6. Create static files folder /public and create index.htm. Test Bootstrap and Angular is working in the browser.
    <!DOCTYPE>
    <html ng-app>
    <head>
    <!-- Latest compiled and minified CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
    
    <!-- Optional theme -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css">
      <title>Contact List App</title>
    </head>
    <body>
      <div class="container">
        <h1>Contact List App</h1>
    <input ng-model="test">
    {test}
      </div>
    
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
    
    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <!-- Latest compiled and minified JavaScript -->
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
    </body>
    </html>

     

  7. Create the controller.js and add the controller to the index.html:
    <!DOCTYPE>
    <html ng-app="myApp">
    <head>
    <!-- Latest compiled and minified CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
    
    <!-- Optional theme -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css">
    
      <title>Contact List App</title>
    </head>
    <body>
      <div class="container" ng-controller="AppCtrl">
        <h1>Contact List App</h1>
      </div>
    
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
    <script type="text/javascript" src="controllers/controller.js"></script>
    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <!-- Latest compiled and minified JavaScript -->
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
    </body>
    </html>

    /controller/controller.js

    var myApp = angular.module('myApp', []);
    myApp.controller('AppCtrl', ['$scope', '$http', function($scope, $http) {
        console.log("Hello World from controller");
    }

     

  8. Refresh page with the Chrome console open with Crti+Shift+i. You should see logged message.
  9. Setup MongoDB.
  10. Run npm install mongojs and add the following lines to import the library and connect to the database.
    var mongojs = require('mongojs');
    var db = mongojs('contactlist', ['contactlist']);

     

  11. Connect to MongoDB and run the command. Use the arrow key to edit previous commands quickly.
    > cd \mongodb\bin
    > mongo
    MongoDB shell version: 3.0.7
    connecting to: test
    > show dbs
    contactlist  0.078GB
    local        0.078GB
    test         0.078GB
    > db.contactlist.insert({name: 'Tom', email: 'tom@testemail.com', number: '(444) -444-4444'})
    WriteResult({ "nInserted" : 1 })
    > db.contactlist.find()                                                                                             
    { "_id" : ObjectId("5657841ef1654874c51c7524"), "name" : "Tracy", "email" : "tracy@testemail2.com", "number" : "(555
    )-555-555" }                                                                                                        
    { "_id" : ObjectId("5657841ef1654874c51c7525"), "name" : "Tucker", "email" : "tucker@testemail3.com", "number" : "(9
    99)-777-7777" }                                                                                                     
    { "_id" : "5657a15ddcc7066c30761fb9", "name" : "dave" }                                                             
    { "_id" : ObjectId("5657a15adcc7066c30761fb8"), "name" : "tom", "email" : null, "number" : null }                   
    { "_id" : ObjectId("5657a159dcc7066c30761fb7"), "name" : "carig", "email" : null, "number" : null }                 
    { "_id" : ObjectId("565b6923d4299337be0b182d"), "name" : "Tom", "email" : "tom@testemail.com", "number" : "(444)-444-4444" }
    >db.contactlist.find().pretty()
    {
            "_id" : ObjectId("5657841ef1654874c51c7524"),
            "name" : "Tracy",
            "email" : "tracy@testemail2.com",
            "number" : "(555)-555-555"
    }
    {
            "_id" : ObjectId("5657841ef1654874c51c7525"),
            "name" : "Tucker",
            "email" : "tucker@testemail3.com",
            "number" : "(999)-777-7777"
    }
    { "_id" : "5657a15ddcc7066c30761fb9", "name" : "dave" }
    {
            "_id" : ObjectId("5657a15adcc7066c30761fb8"),
            "name" : "tom",
            "email" : null,
            "number" : null
    }
    {
            "_id" : ObjectId("5657a159dcc7066c30761fb7"),
            "name" : "carig",
            "email" : null,
            "number" : null
    }
    {
            "_id" : ObjectId("565b6923d4299337be0b182d"),
            "name" : "Tom",
            "email" : "tom@testemail.com",
            "number" : "(444) -444-4444"
    }
    

     

  12. Insert multiple items using [ ] square bracket to hold collections {}
    >db.contactlist.insert([{name: 'Tracy', email: 'tracy@testemail.com', number: '(555)-555-5555'},{name: 'Tucker', email: 'tucker@testemail.com', number: '(666)-666-6666'}])
    BulkWriteResult({
            "writeErrors" : [ ],
            "writeConcernErrors" : [ ],
            "nInserted" : 2,
            "nUpserted" : 0,
            "nMatched" : 0,
            "nModified" : 0,
            "nRemoved" : 0,
            "upserted" : [ ]
    })

 

Sample Contact List App

/public/index.html

<!DOCTYPE>
<html ng-app="myApp">
<head>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">

<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css">

  <title>Contact List App</title>
</head>
<body>
  <div class="container" ng-controller="AppCtrl">
    <h1>Contact List App</h1>
    <table class="table">
      <thead>
        <tr>
          <th>Name</th>
          <th>Email</th>
          <th>Number</th>
          <th>Action</th>
            		<th>&nbsp;</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td><input class="form-control" ng-model="contact.name"></td>
          <td><input class="form-control" ng-model="contact.email"></td>
          <td><input class="form-control" ng-model="contact.number"></td>
          <td><button class="btn btn-primary" ng-click="addContact()">Add Contact</button></td>
          <td><button class="btn btn-info" ng-click="update()">Update</button>&nbsp;&nbsp;<button class="btn btn-info" ng-click="deselect()">Clear</button></td>
        </tr>
        <tr ng-repeat="contact in contactlist">
          <td>{{contact.name}}</td>
          <td>{{contact.email}}</td>
          <td>{{contact.number}}</td>
          <td><button class="btn btn-danger" ng-click="remove(contact._id)">Remove</button></td>
          <td><button class="btn btn-warning" ng-click="edit(contact._id)">Edit</button></td>
        </tr>
      </tbody>
    </table>
  </div>

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script type="text/javascript" src="controllers/controller.js"></script>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
</body>
</html>

/controller/controller.js

var myApp = angular.module('myApp', []);
myApp.controller('AppCtrl', ['$scope', '$http', function($scope, $http) {
    console.log("Hello World from controller");

    var refresh = function() {
      $http.get('/contactlist').success(function(response) {
      	console.log("I got the data I requested");
      	$scope.contactlist = response;
      	$scope.contact = "";
      });
  };

  refresh();

    $scope.addContact = function() {
    	console.log($scope.contact);
    	$http.post('/contactlist', $scope.contact).success( function(response) {
    		console.log(response);
    		refresh();
    	});
    };

    $scope.remove = function(id) {
    	console.log(id);
    	$http.delete('/contactlist/' + id).success(function(response) {
    		refresh();
    	});
    };

    $scope.edit = function(id) {
    	console.log(id);
    	$http.get('/contactlist/' + id).success(function(response) {
    		$scope.contact = response;
    	});
    };

    $scope.update = function() {
    	console.log($scope.contact._id);
    	$http.put('/contactlist/' + $scope.contact._id, $scope.contact).success(function(response) {
    		refresh();
    	});
    };

    $scope.deselect = function() {
    	$scope.contact = "";
    }

}]);

 

/server.js

var express = require('express');
var app = express();
var mongojs = require('mongojs');
var db = mongojs('contactlist', ['contactlist']);
var bodyParser  = require('body-parser');

app.use(express.static(__dirname + "/public"));
app.use(bodyParser.json())

app.get('/contactlist', function(req, res) {
  console.log("I recevied a get request");

  db.contactlist.find(function(err, docs) {
    console.log(docs);
    res.json(docs);
  });
});

app.post('/contactlist', function (req, res) {
  console.log(req.body);
  db.contactlist.insert(req.body, function(err, doc) {
    res.json(doc)
  });

});

app.delete('/contactlist/:id', function(req, res) {
    var id = req.params.id;
    console.log(id);
    db.contactlist.remove({_id: mongojs.ObjectId(id)}, function (err, doc) {
      res.json(doc);
    });
});

app.get('/contactlist/:id', function(req, res) {
  var id = req.params.id;
  console.log(id);
  db.contactlist.findOne({_id: mongojs.ObjectId(id)}, function (err, doc) {
    res.json(doc);
  });
});

app.put('/contactlist/:id', function(req, res) {
  var id = req.params.id;
  console.log(req.body.name);
  db.contactlist.findAndModify({query: {_id: mongojs.ObjectId(id)},
    update: {$set: 
      {
        name: req.body.name, 
        email: req.body.email,
        number: req.body.number
      }
    },
    new: true}, function( err, doc) {
      res.json(doc);
  });
});

app.listen(3000);
console.log("Server running on port 3000");

 

 

Tutorials

 

Code Samples

 

Videos

  • MEAN Stack RESTful API Tutorial (1/5) – Using MongoDB, Express, Angular JS, and Node JS Together – YouTube

    Learn how to use the MEAN stack to create a contact list app. This MEAN stack tutorial is broken into concrete chunks to help you follow along more easily. P…

    Source: www.youtube.com/watch?v=kHV7gOHvNdk

  • How to build a M.E.A.N web application – YouTube

    In this presentation, I provide a COMPLETE walkthrough on how to build an AngularJS application that communicates to CRUD complete NodeJS REST server. This i…

    Source: www.youtube.com/watch?v=OhPFgqHz68o

 

References

Download Attachments

  • index
    Contactlist App with Protractor in root folder
    File size: 2 KB Downloads: 81
  • js controller
    Contactlist App with Protractor tests in folder /controller
    File size: 1 KB Downloads: 79
  • js server
    Contactlist App with Protractor in root folder
    File size: 1 KB Downloads: 79