Introduction

This tutorial is made up of a series of smaller tutorials which go over different parts of the MEAN (Mongodb, ExpressJS, AngularJS, Node.js).

Finally, in this tutorial we will complete the MEAN Stack by modifying the previous version to now use AngularJS. AngularJS is an extensible toolset for building the framework most suited to your application development. It lets you extend HTML vocabulary for your application resulting in an environment that is expressible, readable and quick to develop. The code for this tutorial is available here.

Creating the AngularJS Module

The first file we will modify will be userManager-client.js. Let’s take a look at the different parts of this file.
First we are creating an angular module called ‘userManagerApp’ that references the ngRoute module. The ngRoute module is used for defining routes in the module. After creating the module, we define the root route and assign it the ‘userManagerController’, which we create later in the file.

var app = angular.module('userManagerApp', ['ngRoute']);
app.config(['$routeProvider', function ($routeProvider) {
    $routeProvider.when('/', {
        controller: 'userManagerController',
        templateUrl: '/'
    })
    .otherwise({ redirectTo: '/' });
}]);

Next we add a data factory to the model. A factory creates and returns an object which can be used for data access or generally anything, in this case the object is used for connecting to the REST service. Notice that we have a method for each of the REST service actions.

angular.module('userManagerApp').factory('dataFactory', ['$http', function($http) {
    var dataFactory = {};
    dataFactory.getUsers = function () {
        return $http.get('/users');
    };
    dataFactory.getUser = function (id) {
        return $http.get('/users/' + id);
    };
    dataFactory.insertUser = function (user) {
        return $http.post('/users', user);
    };
    dataFactory.updateUser = function (user) {
        return $http.post('/users/' + user._id, user)
    };
    dataFactory.deleteUser = function (id) {
        return $http.delete('/users/' + id);
    };
    return dataFactory;
}]);

Finally, we create the controller. Our ‘userManagerController’ creates a method for each of the actions that we want to call on the dataFactory from the web page. Notice that we are creating a variable “users” on the $scope object. This will allow us to iterate through the users on the Jade template using AngularJS. More on that later.

angular.module('userManagerApp')
  .controller('userManagerController', [
    '$scope', 'dataFactory', function ($scope, dataFactory) {
    $scope.users;
    getUsers();
    function getUsers() {
        dataFactory.getUsers()
            .success(function (users) {
                $scope.users = users;
            })
            .error(function (error) {
                alert('Unable to load user data: ' + error.message);
            });
    }
    $scope.insertUser = function (user) {
        dataFactory.insertUser(user)
            .success(function () {
                window.location.href = "/";
            }).
            error(function(error) {
                alert('Unable to insert user: ' + error);
            });
    };
    $scope.deleteUser = function (userId) {
        dataFactory.deleteUser(userId)
            .success(function () {
                window.location.href = "/";
            }).
            error(function(error) {
                alert('Unable to delete user: ' + error);
            });
    };
    $scope.updateUser = function (user) {
        dataFactory.updateUser(user)
            .success(function () {
                window.location.href = "/";
            }).
            error(function(error) {
                alert('Unable to update user: ' + error);
            });
    };
}]);

Modifying the Jade Template

Now, to wire it all together we will be modifying the index.jade file. Let’s take a look at the different parts of this file. First, notice that we add the angular.min.js and angular-route.min.js scripts to the file. Then we modify our table object to use the attribute ng-app and give it the value of our AngularJS module that we created in the previous file.

extends layout
block content
  script(src='https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js')
  script(src='http://code.angularjs.org/1.2.0-rc.2/angular-route.min.js')
  script(src='http://code.jquery.com/jquery-1.9.1.js')
  script(src='/javascripts/userManager-client.js')
  h1= title
  table(ng-app="userManagerApp")
    thead
      tr
        th(class='dataColumn') ID
        th(class='dataColumn') Name
        th(class='dataColumn') City
        th(class='dataColumn') State
        th

Next we set the tbody to use the userManagerController by including the attribute ng-controller. Now that we are in the scope of the userManagerController, we can use the “users” variable. We use this variable in the attribute ng-repeat, where we create a loop, so this will run creating a new tr element and all sub-elements for each user object in the users list.

In addition, we use the ng-class-even and ng-class-odd to style the rows differently on even and odd rows.

    tbody(ng-controller="userManagerController")
      tr(ng-repeat="user in users",ng-class-even="'even'",ng-class-odd="'odd'")

Now, inside the tr element, we create our td elements in the template, For the first we just want to display the user ID, so we use the {{user._id}} angular expression. Each of the following td elements have an input field, which we bind to the user properties using the ng-model attribute. Since these variables are bound to the input object, when we call the updateUser(user) method on the button, the values are updated to whatever was typed in the input fields.

The ng-click element is used by the buttons to fire off the events using the $scope object’s methods. You will notice that although we are binding all of these variables and updating them, there are no selectors required in any of the code. In AngularJS, you should never need to put selectors in your code, all variables are bound to components and handled internally by AngularJS.

        td(ng-model="user._id") {{user._id}}
        td
          input(class='inputField',ng-model="user.name")
        td
          input(class='inputField',ng-model="user.city")
        td
          input(class='inputField',ng-model="user.state")
        td
          button(ng-click=('updateUser(user)')) Update
          button(ng-click=('deleteUser(user._id)')) Delete

Finally, we create one more row for the “Add User” section. This one again uses ng-model to bind the input fields to the user properties and then uses the ng-click attribute to handle the inserting of the user using the controller.

      tr(class='odd')
        td
        td
          input(class='inputField',ng-model="user.name")
        td
          input(class='inputField',ng-model="user.city")
        td
          input(class='inputField',ng-model="user.state")
        td
          button(id='btnAdd',ng-click="insertUser(user)") Add User

That was much simpler than the standard jQuery/AJAX way of doing things. I hope you have enjoyed this tutorial and are as excited about the capabilities provided by the MEAN stack as I am. Download the code for this tutorial from github and play around with it, you will find that it’s very easy to throw together prototypes like this using the MEAN Stack.

The following two tabs change content below.

Rocky Pulley

Solutions Architect at QAT Global
is a Solutions Architect at QAT Global and has been working as a software development consultant for over 15 years. Most of his recent work has been focusing on Web 2.0 technologies and mobile application development. @rockytriton