Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / HTML

Node.js introduction using MEAN stack with WebMatrix

4.64/5 (6 votes)
7 Sep 2014CPOL21 min read 28.8K   241  
Introduction to building a web application using Node.js along with Angular.js

Introduction

This article will guide you to start building up a website using Node.js using the MEAN stack. I will try to also help you with setting up your basic tools/infrastructure for developing the application like setting up node.js, mongodb, etc. I am assuming you have some basic knowledge about Node.js and JavaScript along with HTML, etc. However, even if you are new to node.js or the other technologies involved, don't worry, as the article involves a couple of different technologies, I'll just try to scratch the surface.

What does the MEAN acronym stand for?

  • M - MongoDB (NoSQL document store database)
  • E - Express (Web framework for use in Node.js)
  • A - Angular.js (Client side JavaScript MVC framework)
  • N - Node.js

The advantage of using this MEAN stack is all the components are very robust and popular and Javascript is used as the common language on both the client and server side. Also Node.js and MongoDB couple together very well.

I will define the popular technology stack below by category which is popularly used. I might not be using all the technology stated below in details but knowing the entire stack would help know what fits where.

Technology Stack Classified

Client

  • HTML5/CSS3
  • Angular.js as MVC framework
  • Javascript/Jquery
  • Bootstrap for responsive design

Server

  • Node.js

Data Access and ORM

  • Mongoose

Database

  • MongoDB

Keep in mind that although we are using the term ORM above in Data access, these NoSQL databases don't define any schema so Mongoose might be a bit different than the other Object Relational Mappers like NHibernate or Entity Framework.

Let's Get Started

Install Nodejs

You can install Node.js from this official site http://www.nodejs.org/. Just make sure you select all the components in the Custom Setup of the install wizard.

I will be using Microsoft Web Matrix as an IDE which is free and you can install it from the below link. (You might want to choose your own IDE or even use Notepad.)

After installation, open webmatrix and you will see an interface like the one below:

Image 1

Click the Options icon on the lower right corner where we will set our path to the project.

Image 2

Change the Default site location to a path of your choice and click Save. The projects that you create using WebMatrix will reside on that path.

Now on the startup screen, click New and select Template Gallery. Select the Node.js tab on the left menu bar and select "Empty Site" as template. Enter a Site Name for your project too.

Image 3

Click Next and WebMatrix will download the install the template for us. Now you would be able to see the Nodejs project that was created for us as shown below:

Image 4

Here, we see some files like server.js, package.json, web.config, etc. We'll look into the details soon.

Firstly, open server.js file and we see that some template code is already written there as shown above. I am highlighting the piece of code which writes "Hello, world NodeJS". Just click on Run on the top left corner and a browser will spawn up with a text of Hello World. So we have our first Node.js program up and running thereby verifying that Nodejs and webmatrix are installed properly.

Ok, so now, let's try to run our program without using WebMatrix just using our good old Command Prompt.

Open cmd(Command Prompt in Administrator mode-Right click and Run as admin) and go to the path where the project files live. Type "node server.js" means using node.exe, run the file server.js. Node.exe is the main executable file for running Nodejs.

Image 5

And here, we get an error which is because we had run our program using matrix already and so port 8080 is already in use. I got this error while running so I am sharing it with you just in case you get it too.

Let's just change the port number to 8081 in server.js file in the last line and run the program again.

Image 6

Now open a browser and browse http://localhost:8081/ and we would see the hello world again. So now, we saw that with just the command prompt, we are able to run our node.js program. We'll come back to the details of the server.js file later, but before that, let's try to get some node.js concepts cleared.

package.json

The package.json file contains information about our project like the project name, version, author, etc. It also contains a dependencies property which we'll explore later.

Modules (using require())

To follow good programming practices and write modular code, we will write our JavaScript code in different files and each file will represent a certain module.

Node.js uses a concept of requiring files (which actually represent modules) in a file so that we can use the methods of that file which we included by doing a "require". Sounds confusing, let's do a sample.

Let's create a file and name it employee.js.

Every node.js file has something called module.exports which is kind of an object in OOPS terms. So we can create properties using the "module.exports" keyword.

employee.js

JavaScript
module.exports.firstname = "Rajiv";
module.exports.lastname = "Gogoi";
module.exports.department = "Computer Science";
module.exports.address = {
    city : "Mumbai",
    country : "India"
};

So this employee.js file or module contains four properties, three simple properties like firstname, lastname, department and one complex property named address.

Now let's create another file named main.js which would reference this employee.js file using the require feature.

main.js

JavaScript
var employee = require("./employee.js");
console.log(employee.firstname + " " + employee.lastname);
console.log(employee.address.city + ", " + employee.address.country);

var employee = require("./employee.js");

So the above line of code uses the node.js require method and passes in a path(./ means same directory) to the employee.js file which returns an object that we assign to the variable employee. After that, we log the property values to the console using the employee object.

Note: Please note here that employee.js is a file here directly under the project but we could as well create a folder and place our .js files under it and use the relative path. In larger applications, we would want to create folders and keep our related js files under folders for better management and maintenance.

Let's open up our cmd prompt, get to the project path and try running this main.js file.

Image 7

Ok, so we saw how to create a module using the require() method and get/set properties. Now let's try to create another module which actually represents a class (let's get more closer to OOPS).

Let's create a file customer.js that has the code below. This piece of code will return a function which we will simulate as a Class. For those who know constructor functions in JavaScript, the usage below is the same. http://www.javascriptkit.com/javatutors/oopjs2.shtml

JavaScript
module.exports = function () { 
    this.customername = "TopBank",
    this.location = "Florida",
    this.employeestrength = 10000
};

Now let's go to our main.js file again and write the following piece of code below that was already written above.

We'll use require as before, but this time, it will return a function which will represent the Customer class. After that, we will create an object of the Customer class using the new keyword.

JavaScript
var employee = require("./employee.js");
console.log(employee.firstname + " " + employee.lastname);
console.log(employee.address.city + ", " + employee.address.country);

//Let's require customer.js which in this case will represent class customer.
var Customer = require("./customer.js");
//Now let's create a new object of Customer class.
var objCustomer = new Customer();
console.log(objCustomer.customername);
console.log(objCustomer.location);
console.log(objCustomer.employeestrength);

Node Package Manager(NPM)

NPM is a functionality by which we can install node.js packages from the internet. For those coming from the .NET background, it's similar to Nuget. We have similar package managers for Java too e.g.jpm4j.

https://www.npmjs.org/ lists out the libraries available in node.js for us to use.

Now, let's install Node.js express library, yes the E from the MEAN acronym using npm using the following command:

npm install express --save

Here --save is optional which actually mentions that please go ahead and save express library as a dependant library for the current project. The effect is in the package.json file (in the main project folder), we will have a dependencies property with express as the value. The benefit is that when we will use source control, we don't have to checkin these npm modules there. Whenever a new user will checkout the node.js project, the package.json file will see the npm dependencies and install them.

Image 8

After installation, we will see that in our project folder, we will have a new folder node_modules which will contain the express library files.

Image 9

The beauty of npm is it does dependency management for child libraries too, e.g., our express module might also depend on some other modules. So the way it will work is the express folder under node_modules folder will also have a package.json file where it will again define the dependencies.

server.js

Ok, so sometime before, we saw our server.js file returning a "Hello World" response to our browser. Now let's try to get into the details of this file and try changing it a bit and get some explanation of what each line does.

JavaScript
//Let's require the http module which will take care of listening to HTTP requests. 
//http is a built
//in node.js library
var http = require('http');

//Let's create our Web Server passing a callback function with request/response as parameters.
var server = http.createServer(function (req, res) {
    //Write out response headers of 200 successful and content type.
    res.writeHead(200, { 'Content-Type': 'text/html' });

    //Write out a piece of our everlasting Hello World string
    // Notice that we are using the request object to write our the host header.
    res.write("Hello Node.js, are you running fine on host " + req.headers.host + "\n");
    
    //End the response else the request will keep hanging.
    res.end();
})

// Make sure server is listening on port 8081.
server.listen(process.env.PORT || 8081);

Let's Get Started

Now that we have setup node.js, gained some basic concepts and run some programs, let's try to build something using the MEAN stack as promised.

We have already installed the "Express" library above using npm. The "Express" library will help us build our web server in a relatively easier way because it will serve as our web framework. So we will have library functions to do most of the stuff like HTTP GET/POST, etc., send data to the client and won't have to deal with things like res.end() for manually ending the response. Instead, Express library will act as an abstraction layer so that we can concentrate on our application logic and not have to deal with lower level responsibilities. So let's modify the server.js file to use the Express library.

JavaScript
//Let's require the http module which will take care of listening to HTTP.
var http = require('http');

//Let's require the express module which will return a function that we will call
var express = require('express');

//Let's call express as a function which will return an application object 
var application = express();

//Let's use the application object to do something on an HTTP GET request.
application.get("/", function (req, res) {
    // Set the response header content type
    res.set("Content-Type", "text/html");
    // Send some HTML back as response.
res.send("Hello using express get");
})
//Let's create our Web Server passing the application object. 
var server = http.createServer(application) 
// Make sure server is listening on port 8081. 
server.listen(process.env.PORT || 8081);

Now let's try to run our program, either click Run on the top left of Web matrix or use the command prompt to run the node server.js file. In either case, you will see the browser, displaying the Hello text sent back from the server.

View Engines

Till now, we were sending text/html from the server directly using write() or the send() function, but in real life applications, we would want to use a view engine where we can write our HTML. Node.js has different view engines like Jade, EJS or Vash and what to choose is entirely upon the syntax taste that pleases one. For this article, I will be using the Vash view engine.

Let's install the vash library using the following command:

npm install vash --save

Now that vash is installed, let's re-write our server.js file to use the vash view engine and set the response to render a view.

server.js

JavaScript
//Let's require the http module which will take care of listening to HTTP requests.
var http = require('http');

//Let's require the express module which will return a function that we will call
var express = require('express');

//Let's call express as a function which will return an application object.
var application = express();

// Setting the View Engine to Vash. "view engine" is the key.
application.set("view engine", "vash");

//Let's use the application object to do something on an HTTP GET request.
application.get("/", function (req, res) {
    // We'll use the render method of the response object passing "index" 
    // as the filename(1st para meter)
    // and a JavaScript object literal as the 2nd parameter.
    // This object literal with firstname and lastname properties 
    // will be passed to the view to be
    // used there.
    res.render("index", {firstname: "Robert", lastname: "Brosnan"});
})

//Let's create our Web Server passing the application object.
var server = http.createServer(application)

// Make sure server is listening on port 8081.
server.listen(process.env.PORT || 8081);

After that, let's create a views folder directly under the project. This views folder will contain the views files. Let's add an index.vash file and add the following piece of code.

index.vash

HTML
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title></title>
    </head>
    <body>
        @model.firstname @model.lastname
    </body>
    </html>

Notice we are using the firstname and lastname properties by appending after @model. Yes, the view treats these properties which are passed to it as model properties.

<meta charset="utf-8" /> <title></title>

Now let's run the program again and we should see the output of Robert Brosnan.

<meta charset="utf-8" /> <title></title>

Adding CSS Resources

Let's add a site.css file to our project to do the styling. We already have a public folder in the main project directory. Let's create the site.css file in that directory. This public folder is the place where all client side static resources should live like CSS, client side .js files, images, etc.

site.css

HTML
body {
    background-color: #b6ff00;
}

Link the site.css file in the index.vash view:

HTML
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title></title>
        <link href="site.css" rel="stylesheet" />
    </head>
    <body>
        @model.firstname @model.lastname
    </body>
    </html> 

Now if we run our site again using the Run button from within WebMatrix, we should see a background color which means the site.css is being used. However, if we try running our node server using the command prompt, going to our project path and doing "node server.js", and then try running the site from a browser, we will notice that we don't see the background color. If we use developer tools in the browser(F12), we can see that the site.css is not found.

Image 10

So why do we have a difference when we try running the site directly from WebMatrix and when we try to run the node server from command prompt? Why when we run the site from WebMatrix, it's able to find the site.css find within the public folder.

The reason is because, when we run the site from WebMatrix, it uses IISExpress to host the node server and IISExpress uses a configuration file web.config which you might have noticed in the project directory already.

Please note that this web.config file is not necessary to run node.js and only the WebMatrix IDE created this file to host it in Microsoft IIS web server (IISExpress in our case). When we run the node.js server using command prompt, it doesn't read the web.config.

Image 11

If we have a look at the web.config file, we can see that there is a rule set which sees the incoming url that matches a physical file in the public folder. So this rule effectively helps our request find the site.css file inside the public folder.

But does it mean that when we run the node server using command prompt, we won't be able to use CSS files, obviously not. To identify the public folder, when we run using command prompt, we need to set the public folder as the static resources folder. To do that, open the server.js file and write the following line of code after the line of code setting the view engine. I have also used console.log to print the __dirname so you can see that it points to the physical directory of our node.js project.

JavaScript
// Setting the View Engine to Vash. "view engine" is the key.
application.set("view engine", "vash");

// Let's set the public folder as static resources folder.
// __dirname points to the node.js physical project directory.
console.log(__dirname);
application.use(express.static(__dirname + "/public"));

So now when we run our project, we should see our beautiful background in the browser. :)

Bower For Front End Package Management

Just like we are using npm for server side package management, we will use a client side package manager named "Bower" for installing the client side resources like jquery, bootstrap, knockout, angular, etc.

So let's first install Bower using the following npm command.

npm install bower --save-dev

Notice the use of this new optional flag --save-dev. This means this is only a development dependency and we don't need this package on the production server. Of course, why will we need a client side package manager on our production server.

Image 12Image 13

See the package.json file in the below snapshot.

Image 14

To use bower, we need a configuration file named .bowerrc where we will put a json indicating where to save the client side resources. So let's create a new file under the project directory and name it .bowerrc and paste the following piece of json.

Image 15

So this piece of json tells bower to install the client side resources in the public lib folder.

Now that we have configured bower, let's use it to install jquery.

Image 16

We will notice that jquery is downloaded in the public/lib directory.

Tips and Tricks

Till now, we had to manually restart our node.js application every time we made changes in our server side code so that the changes get reflected. However, there is a node.js development utility available named "nodemon" which monitors changes in the node application and automatically restarts the server. Cool isn't it, so now we save some time in not having to restart our server after new changes.

To install nodemon, let's use the following command:

npm install nodemon -g

Image 17

This time we introduced another switch -g which means install globally so that nodemon will be available for all node.js projects on this machine not only our current project.

Now let's run our server.js file but this time using nodemon.

nodemon server.js

Image 18

Now try to make any changes to the server side code like changing the firstname property, etc. and refresh the browser and you will be delighted to see the changes instantly. :)

REST Service

Now that we have ran a couple of node.js programs, used vash as the view engine, decorated with CSS, etc., let's build up a REST service to be consumed later by a client side library Angular.js.

Let's first create a controllers folder inside our node project. We are calling the folder controllers because it will be controlling the request to get some model(data) and return to the view, yes the C of the MVC design pattern.

Inside the controllers folder, let's create a JavaScript file named employeeController.js. This file will be the main file for our application which we will use to display employees and insert employees. Yes, that's the piece of functionality we will be building using the MEAN stack. We will be using a JavaScript self executing anonymous function to keep the code readable and modular. To learn more about self executing anonymous functions, you can go through http://esbueno.noahstokes.com/post/77292606977/self-executing-anonymous-functions-or-how-to-write.

Before our REST service starts returning json, etc., let's try to do something simpler what we were doing before, i.e., returning the view index.vash but by using the employeeController.

JavaScript
(function (employeeController) {
    //By using employeeController as a parameter in the anonymous function
    // we are replacing it with module.exports so that we can start adding functions to it.
    // So we have a function named init which accepts an application parameter.
    // This application parameter will be passed from the server.js file, yes
    // the application object that we created using express library.
    employeeController.init = function(application){
        //Here we are doing the very same thing that we did in server.js 
        // routing a GET request to the root of the site "/" and returning the index.vash view
        application.get("/", function(req, res){
            res.render("index", {firstname: "John", lastname: "Brosnan"});
        })
    }
})(module.exports);

And we'll have to change our server.js file to make a call to the employeeController's init function. And we of course, don't need the call to application.get() in the server.js file because we moved that piece of code to the employeeController.js init method.

JavaScript
var employeeController = require("./controllers/employeeController");
employeeController.init(application); 

Now if we try to run our application, we should see the same output in the browser, but this time we used a controller to handle the GET request and return the response to the view.

Let's now modify our employeeController.js file to expose an API endpoint which accepts a GET request and returns some json as data. This is actually simple, what we have to do is in the application.get() function, we have to return json using the send function instead of using the render() function which actually renders a view.

JavaScript
(function (employeeController) {
    //By using employeeController as a parameter in the anonymous function
    // we are replacing it with module.exports so that we can start adding functions to it.
    // So we have a function named init which accepts an application parameter.
    // This application parameter will be passed from the server.js file, yes
    // the application object that we created using express library.
    employeeController.init = function (application) {
        //Here we are doing the very same thing that we did in server.js 
        // routing a GET request to the root of the site "/" and returning the index.vash view
        application.get("/", function (req, res) {
            // Set response headers, content type to json
            res.set("Content-Type", "application/json");
            // Send a json object back. 
            res.send({employeeName: "Tommy Jones"});
        })
    }
})(module.exports);

Now try running the applicaiton and we will see json data being returned.

Image 19

Let's Get Angular

AngularJs is a client side data binding library similar to KnockoutJs if you have used it. I won't go into the details of Angularjs here as there are many tutorials on the internet. What I'll be doing is just show a sample of how to use AngularJs with Node.js.

So let's first install Angularjs using the bower tool with the following command:

bower install angular-bootstrap

This will install both angular and bootstrap library (for responsive UX design).

Now let's include the angular and bootstrap script in our index.vash file.

HTML
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title></title>
    </head>
    <body>
        @model.firstname @model.lastname
        <script src="/lib/jquery/dist/jquery.js"></script>
        <script src="/lib/angular/angular.js"></script>
        <script src="/lib/angular-bootstrap/ui-bootstrap.js"></script>
    </body>
    </html> 

Let's create a folder named scripts under our public folder which will contain our client side JavaScript files.

And we'll add a file named empViewdata.js. This file contains a JavaScript self executing anonymous function, yes same pattern that we used for the server side scripts. It contains the angular module which we are naming "empViewdata" and the angular controller named "empController". To the self executing function, we are passing the window.angular object so that we can start using angular library functions. The angular module is a piece of modular code, which defines the dependencies of the module and contains the controllers.

JavaScript
(function (angular) {
    // Let's create a module named empViewdata and the 2nd parameter is an empty array where
    // we can define any dependencies that this module needs. Empty means our module has
    // no dependencies.
    // 1st parameter is the module name which the view will use as ng-app attribute.
    var module = angular.module("empViewdata", []);

    // Create the controller, 1st parameter is the controller name which 
    // the view will use and the
    // 2nd parameter will be an array.
    // This array will have a variable named $scope, which is nothing but the viewmodel.
    // the viewmodel $scope will have the properties that the view needs.
    // $scope will have one property named employees which will contain an array of objects, 
    // each object will have one property named "name".
    module.controller("empController",["$scope",
        function($scope){
            $scope.employees = [{name: "Roger Peter"},
                                {name: "Lovely Planet"},
                                {name: "Roudie Moore"}]
        }
    ])
})(window.angular); 

$scope is an object that Angular provides which we can use to return the data to the view. In a later part, we'll see the usage of another such angular object named $http.

So we have our Angular module and controller ready to return the viewmodel data using the $scope object, let's write our view to use the Angular objects so that the view can do data binding using Angular.

index.vash

HTML
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title></title>
        <link href="site.css" rel="stylesheet" />
    </head>
    <body>
        <div ng-app="empViewdata">
            <div ng-controller="empController">
                <div ng-repeat="e in employees">
                {{ e.name }}
                </div>
            </div>
        </div>
        <script src="/lib/jquery/dist/jquery.js"></script>
        <script src="/lib/angular/angular.js"></script>
        <script src="/lib/angular-bootstrap/ui-bootstrap.js"></script>
        <script src="/scripts/empViewdata.js"></script>
    </body>
    </html> 

<script src="/lib/jquery/dist/jquery.js"></script><script src="/lib/angular/angular.js"></script><script src="/lib/angular-bootstrap/ui-bootstrap.js"></script><script src="/scripts/empViewdata.js"></script>

View angular attributes explanation:

  • ng-app --> This angular attribute will contain the value of an angular module in our case "empViewdata" which we wrote earlier. Effectively, this div will be the container within which our angular objects will reside. We can have multiple ng-app attributes on a single page so that different sections of the page can be assigned different tasks by assigning to different angular modules.
  • ng-controller --> This angular attribute will be responsible for controlling the view actions like serving data to a view, handling events like click, dropdown change, etc. In our case, the controller name is "empController" which is sending the viewmodel to the view. Just like ng-app, there can be multiple controllers in a view doing different actions. Please note that this is the client side controller for angular to use. The server side controller that we created earlier "employeeController" is the node.js controller which handles HTTP GET/POST requests from the browser.
  • ng-repeat --> This attribute specifies that this <div> will repeat number of times to the value of items in the collection. It is similar to a foreach loop that many languages like C#, JavaScript, have. The expression "e in employees" means e is a local variable that will execute each time in the loop and employees is a collection. We already saw that the $scope, employees contains a number of employee names in an array. So we are essentially trying to loop through the employees collection.
  • {{ e.name }} --> The double curly braces syntax means, we would like to bind some data within it. Here using our local variable e, we are displaying the name of the employee(e.name).

So that's it for the view. Ok, so now, let's just change the server side node.js controller employeeController to render our initial index.vash view instead of a json response.

JavaScript
res.render("index");

Now try running the site using a browser and you will be able to view the employee names.

Ok, so we used angular to return a hard coded collection of employee names and display it to the view. But in a real world application, that data will be coming from some data source and being served by some service. So let's resume our work back to the REST service that we created earlier.

We'll add another GET event handler to the employeeController.js file as shown in the code snippet below. This get handler will route to url requests "/api/employee" and will return a json collection of employee names.

JavaScript
(function (employeeController) {
    //By using employeeController as a parameter in the anonymous function
    // we are replacing it with module.exports so that we can start adding functions to it.
    // So we have a function named init which accepts an application parameter.
    // This application parameter will be passed from the server.js file, yes
    // the application object that we created using express library.
    employeeController.init = function (application) {
        //Here we are doing the very same thing that we did in server.js 
        // routing a GET request to the root of the site "/" and returning the index.vash view
        application.get("/", function (req, res) {
            res.render("index");
        })
        application.get("/api/employee", function (req, res) {
            // Set response headers, content type to json
            res.set("Content-Type", "application/json");
            // Send a json collection object back. 
            res.send([{ name: "Roger Peters" },
                                { name: "Lovelys Planet" },
                                { name: "Roudie Moores"}]);
        })
    }
})(module.exports);

And back to our angular module, where we'll do an ajax HTTP GET call to this "/api/employee" which will return a json collection and we'll happily bind it using angular as done before but this time not with a hard coded collection but data returned from a REST service. To achieve this, we'll use the $http angular object and make a get() request similar to the jquery get request to the url "/api/employee". $http uses something called a JavaScript promise pattern which is kind of a callback we define on the then() method. Then then() method takes 2 functions as parameters, one for success and the second for failure.

Learn more about JavaScript promises https://www.promisejs.org/:

JavaScript
(function (angular) {
    // Let's create a module named empViewdata and the 2nd parameter is an empty array where
    // we can define any dependencies that this module needs. Empty means our module has
    // no dependencies.
    var module = angular.module("empViewdata", []);

    // Create the controller and the 2nd parameter will be an array.
    // This array will have a variable named $scope, which is nothing but the viewmodel.
    // the viewmodel $scope will have the properties that the view needs.
    module.controller("empController", ["$scope", "$http",
        function ($scope, $http) {
            $http.get("/api/employee")
                 .then(function (result) {
                     $scope.employees = result.data;
                 },
                 function (error) {
                     // Do something with the error
                     alert("error");
                 });
        }
    ])
})(window.angular);  

Now, let's try running our site again and we should see the employee names returned by the node.js REST service and data binded with angular.

Image 20

Ok, so we are now left with only the "M (MongoDB)" of the MEAN stack. We already used E (Express), A (Angular), N (Node.js), so let's get mongodb :)

MongoDb

Let's download mongodb from https://www.mongodb.org/downloads based on our operating system. And after extracting from the zip file, let's copy the files from the bin directory to one of the directories for our project to use.

Let's also create a folder inside this directory and name it database. This folder will be the container for the data.

Now let's run a command from our cmd to run our mongodb server.

Image 21

Now our mongodb server is up and running. Let's try browsing our mongodb server using a browser, yes mongo web console runs on port 28017.

Image 22

We'll use mongoose as for our data connection between node.js and mongodb. In short, mongoose is sort of an ORM like nhibernate/entity framework using which we can define schemas for our models. Just for our knowledge, MongoDB being a NoSQL database doesn't enforce schemas, but that's another topic though which we'll not discuss here.

Let's install mongoose using the following command:

npm install mongoose.

Now let's write code in our employeeController.js to use mongoose to connect to our mongodb database, create an employee, and retrieve the employees.

employeeController.js

We added the post event handler to this file to handle creation of an employee.

JavaScript
(function (employeeController) {
    //By using employeeController as a parameter in the anonymous function
    // we are replacing it with module.exports so that we can start adding functions to it.
    // So we have a function named init which accepts an application parameter.
    // This application parameter will be passed from the server.js file, yes
    // the application object that we created using express library.
    employeeController.init = function (application) {

        // Mongoose connection - Start
        // Add mongoose library
        var mongoose = require('mongoose');

        // Connect to empdb database, if not exists, mongodb will create.
        mongoose.connect('mongodb://localhost/empdb');

        // define connection
        var db = mongoose.connection;
        db.on('error', console.error);
        db.once('open', function callback() {
            console.log('mongodb connection opened.');
        });

        // define schema and model
        var empSchema = mongoose.Schema({ name: String });
        var Employee = mongoose.model('Employee', empSchema);

        // Mongoose connection - End

        //Here we are doing the very same thing that we did in server.js 
        // routing a GET request to the root of the site "/" and returning the index.vash view
        application.get("/", function (req, res) {
            res.render("index");
        })
        application.get("/api/employee", function (req, res) {
            // Set response headers, content type to json
            res.set("Content-Type", "application/json");
            // Retrieve employees
            Employee.find(function (err, employees) {
                if (err) return console.error(err);
                // Send a json collection object back. 
                res.send(employees);
            });
        });
        // Handle POST request to create employee
        application.post("/api/employee", function (req, res) {
            // Create an employee
            // Get the employee name from the HTTP request body using req.body.empName
            var emp = new Employee({ name: req.body.empName });
            emp.save(function (err, emp) {
                if (err) return console.error(err);
                console.log(emp);
            });
            // Set response headers, content type to json
            res.set("Content-Type", "application/json");
      // Send the inserted employee name back to angular for 
      // databind to the collection employees.
            res.send({ name: req.body.empName });

        });
    }
})(module.exports); 

empViewdata.js

JavaScript
(function (angular) {
    // Let's create a module named empViewdata and the 2nd parameter is an empty array where
    // we can define any dependencies that this module needs. Empty means our module has
    // no dependencies.
    var module = angular.module("empViewdata", []);

    // Create the controller and the 2nd parameter will be an array.
    // This array will have a variable named $scope, which is nothing but the viewmodel.
    // the viewmodel $scope will have the properties that the view needs.
    module.controller("empController", ["$scope", "$http",
        function ($scope, $http) {
            $scope.newEmployee = { empName: "" };

            $http.get("/api/employee")
                 .then(function (result) {
                     $scope.employees = result.data;
                 },
                 function (error) {
                     // Do something with the error
                     alert("error");
                 });
            // Call REST api to create employee
            // $scope.newEmployee is the model object, this model object contains properties
            // attributed with ng-model in the view elements.
            // In our case, we have 1 property newEmployee.empName 
            // in the model properties collection.
            $scope.create = function () {
                $http.post("/api/employee", $scope.newEmployee)
                     .then(function (result) {
                         // Push the added employee to the collection of employees.
                         $scope.employees.push(result.data);
                     })
            };
        }
    ])
})(window.angular);  

Change index.vash to include a textbox and a submit button to add employees.

  • ng-submit --> This takes a create method which we have defined on our empViewdata.js which makes an $http.post call to the node.js REST service API.
  • ng-model --> It defines a model object to be passed as the body of the HTTP POST request. Contains the properties which are defined on the HTML elements, in our case only one, the text box.
HTML
<div ng-app="empViewdata">
            <div ng-controller="empController">
                <form class="form-horizontal" name="empForm" ng-submit="create()">
                 <div class="form-group">
                  <input type="text" id="empName" ng-model="newEmployee.empName" />
                  <input type="submit" class="btn btn-primary" value="Create" />
                 </div>
                </form>
                <div ng-repeat="e in employees">
                {{ e.name }}
                </div>
            </div>
        </div>

And one last thing, change server.js to include node.js library body-parser which would be able to handle POST requests.

JavaScript
var express = require('express'),
    bodyParser = require('body-parser');

// Setting application to use body parser.
application.use(bodyParser());

Now make sure both the mongodb and node.js server are running, and browse the site. You should be able to view the list of employees and also be able to create employees.

Summary

So in this article, we explored briefly how we can use the MEAN stack to build websites using node.js at the server side. Hope I was able to share my knowledge and it was helpful. Please feel free to ask any questions, I'll try my best to answer your questions. Thanks and keep learning. :)

History

  • 7th September, 2014: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)