Learning AngularJS by Example – The Customer Manager Application

I’m always tinkering around with different ideas and toward the beginning of 2013 decided to build a sample application using AngularJS that I call Customer Manager. It’s not exactly the most creative name or concept, but I wanted to build something that highlighted a lot of the different features offered by AngularJS and how they could be used together to build a full-featured app. One of the goals of the application was to ensure that it was approachable by people new to Angular since I’ve never found overly complex applications great for learning new concepts.

The application initially started out small and was used in my AngularJS in 60-ish Minutes video on YouTube but has gradually had more and more features added to it and will continue to be enhanced over time. It’ll be used in a new “end-to-end” training course my company is working on for AngularjS as well as in some video courses that will be coming out. Here’s a quick look at what the application home page looks like:


In this post I’m going to provide an overview about how the application is organized, back-end options that are available, and some of the features it demonstrates. I’ve already written about some of the features so if you’re interested check out the following posts:


Key Features

The Customer Manager application certainly doesn’t cover every feature provided by AngularJS (as mentioned the intent was to keep it as simple as possible) but does provide insight into several key areas. Here are a few of the features it demonstrates with information about the files to look at if you want more details:

  1. Using factories and services as re-useable data services (see the app/services folder)
  2. Creating custom directives (see the app/directives folder)
  3. Custom paging (see app/views/customers/customers.html and app/controllers/customers/customersController.js)
  4. Custom filters (see app/filters)
  5. Showing custom modal dialogs with a re-useable service (see app/services/modalService.js)
  6. Making Ajax calls using a factory (see app/services/customersService.js)
  7. Using Breeze to retrieve and work with data (see app/services/customersBreezeService.js). Switch the application to use the Breeze factory by opening app/services.config.js and changing the useBreeze property to true.
  8. Intercepting HTTP requests to display a custom overlay during Ajax calls (see app/directives/wcOverlay.js)
  9. Custom animations using the GreenSock library (see app/animations/listAnimations.js)
  10. Creating custom AngularJS animations using CSS (see Content/animations.css)
  11. JavaScript patterns for defining controllers, services/factories, directives, filters, and more (see any JavaScript file in the app folder)
  12. Card View and List View display of data (see app/views/customers/customers.html and app/controllers/customers/customersController.js)
  13. Using AngularJS validation functionality (see app/views/customerEdit.html, app/controllers/customerEditController.js, and app/directives/wcUnique.js)
  14. Nesting controllers
  15. More…

Application Structure


The structure of the application is shown to the right. The  homepage is index.html and is located at the root of the application folder. It defines where application views will be loaded using the ng-view directive and includes script references to AngularJS, AngularJS routing and animation scripts, plus a few others located in the Scripts folder and to custom application scripts located in the app folder.

The app folder contains all of the key scripts used in the application. There are several techniques that can be used for organizing script files but after experimenting with several of them I decided that I prefer things in folders such as controllers, views, services, etc. Doing that helps me find things a lot faster and allows me to categorize files (such as controllers) by functionality. My recommendation is to go with whatever works best for you. Anyone who says, “You’re doing it wrong!” should be ignored. Contrary to what some people think, there is no “one right way” to organize scripts and other files. As long as the scripts make it down to the client properly (you’ll likely minify and concatenate them anyway to reduce bandwidth and minimize HTTP calls), the way you organize them is completely up to you. Here’s what I ended up doing for this application:

  1. Animation code for some custom animations is located in the animations folder. In addition to AngularJS animations (which are defined using CSS in Content/animations.css), it also animates the initial customer data load using a 3rd party script called GreenSock.
  2. Controllers are located in the controllers folder. Some of the controllers are placed in subfolders based upon the their functionality while others are placed at the root of the controllers folder since they’re more generic:


  3. The directives folder contains the custom directives created for the application.
  4. The filters folder contains the custom filters created for the application that filter city/state and product information.
  5. The partials folder contains partial views. This includes things like modal dialogs used in the application.
  6. The services folder contains AngularJS factories and services used for various purposes in the application. Most of the scripts in this folder provide data functionality.
  7. The views folder contains the different views used in the application. Like the controllers folder, the views are organized into subfolders based on their functionality:



Back-End Technologies

The Customer Manager application (grab it from Github) provides two different options on the back-end including ASP.NET Web API and Node.js. The ASP.NET Web API back-end uses Entity Framework for data access and stores data in SQL Server (LocalDb). The other option on the back-end is Node.js, Express, and MongoDB.


Using the ASP.NET Web API Back-End

To run the application using ASP.NET Web API/SQL Server back-end open the .sln file at the root of the project in Visual Studio 2012 or higher (the free Express 2013 for Web version is fine). Press F5 and a browser will automatically launch and display the application.


Using the Node.js Back-End

To run the application using the Node.js/MongoDB back-end follow these steps:

  1. In the CustomerManager directory execute 'npm install' to install Express, MongoDB and Mongoose (package.json).
  2. Load sample data into MongoDB by performing the following steps:
    • Execute 'mongod' to start the MongoDB daemon
    • Navigate to the CustomerManager directory (the one that has initMongoCustData.js in it) then execute 'mongo' to start the MongoDB shell
    • Enter the following in the mongo shell to load the seed files that handle seeding the database with initial data:

    use custmgr

  3. Start the Node/Express server by navigating to the CustomerManager/server directory and executing 'node app.js'
  4. View the application at http://localhost:3000 in your browser.


Front-End Technologies

The Customer Manager application uses the following frameworks and libraries on the front-end:

  1. AngularJS (with the ngRoute and ngAnimation modules)
  2. Bootstrap
  3. Angular UI BootStrap
  4. GreenSock Animations


The application uses native AngularJS $http by default to make calls back to the server. However, by going to app/services/config.js you can switch from using $http to using BreezeJS. When using BreezeJS you’ll also need to include jQuery and Q (these are already loaded in index.html to keep things simple). For more details on what BreezeJS is all about check out my previous post.

  1. BreezeJS 
  2. Q
  3. jQuery


Application Views

The application has several views designed to cover different aspects of AngularJS from editing data to displaying, paging, and filtering data. Here are the main views:


Customers View

This view provides multiple views of customer data (Card View and List View), supports paging, and provides filtering functionality.

Card View (app/views/customers/customers.html)

This view displays customer information and allows customers to be edited (by clicking their name), deleted (by clicking the X), or their orders to be viewed.


List View (app/views/customers/customers.html)

This view display customer information in a standard list type of view.


Customer Edit View (app/customers/customerEdit.html)

This view adds some validation including a custom directive that ensures that the email address being added is unique.


Customer Orders View (app/customers/customerOrders.html)


Orders View (app/views/orders/orders.html)



About View (app/views/about.html)

There isn’t much to this view but I listed it for the sake of completeness.



Custom Directives

Two custom directives are currently included in the application:

  1. Unique value directive (app/directives/wcUnique.js) – This directive ensures that email addresses entered on the customer edit view are unique. It makes a call back to a service and then calls ngModel.$setValidity() to handle showing or hiding an error message. A post on this directive can be read here.


  2. Angular Overlay directive (app/directives/wcOverlay.js) – This directive intercepts XmlHttpRequest calls and displays a custom overlay (tracks AngularJS calls as well as jQuery). The directive is available in the application or as a stand-alone directive on Github.

AngularOverlay Directive Example

Custom Filters

The application includes two custom filters used to filter data in the customers and orders views:

  1. Name/City/State Filter (app/filters/nameCityStateFilter.js)


  1. Name/Product Filter (app/filters/nameProductFilter.js)




I’ll be enhancing the application even more over time and welcome contributions as well. Tony Quinn contributed the initial Node.js/MongoDB code (thanks Tony!) which is very cool to have as a back-end option. Access the standard application here and a version that has custom routing in it here. Additional information about the custom routing can be found in this post.

comments powered by Disqus


  • I loaded this into a Tomcat env and the code has many case issues when it comes to pathing and finding resources.

  • By far the best AngularJs learning resource out there !! Dan, I have a question: I've tried to combine: AngularJs + RequireJs + AngularFire + Firebase, however I'm having problems, AngularFire generates an error saying that angular is not available. Have you tried and succeed on this?
    Thanks !

  • Thanks Dan. Very useful. Learning tons here.

  • Thank you very much.
    It is the one I have been googling for since last month.
    What a great article about angula,node and mongodb!!!

  • Victor:

    I haven't played with Firebase at this point (only looked at a few demos) so I'm not sure what might be causing that error. I'd recommend posting details about what you're seeing to Stackoverlow.com to see if anyone else has experienced that error.


  • Mike,

    Out of the box the app is designed to run with either Web API or Node.js as mentioned above. If you're trying it in a different environment you may have to change paths and things - hard to say since it hasn't been tested/run in a Tomcat environment. It should be pretty straightforward to do though since all of the script references and resources are in index.html.


  • I went through the eBook and got to the $RouteProvider section and then began getting errors. I researched the error and saw that the current version of AngularJS did not include route information and I need to add that script reference as well. I did this, but still I get a Module Injection error.

  • Andy:

    That's correct - they changed that with version 1.2. You'll see that in the sample app above. Make sure your module definition includes ngRoute. Sounds like you already included the angular routing script in your main page.

    var app = angular.module('yourApp', ['ngRoute']);

    See the following example from the app above (it includes other dependencies as well that you won't need):



  • Great intro to AngularJS.
    Keep up the good work.

  • how to solove IE compatibility issues ?

  • Hello Dan,
    Thanks for creating this wonderful tutorial. Heads up from a beginning node/express developer: the package.json file in the CustomerManager directory "pins" the express server to version 3.0.0 like so:

    "name": "CustomerManager"
    , "version": "0.0.1"
    , "private": true
    , "dependencies": {
    "express": "3.0.0"
    , "jade": ">= 0.0.1"
    , "mongodb": ">= 0.9.7-3-5"
    , "mongoose": ">= 2.4.10"
    , "connect-mongodb": ">= 1.1.3"
    , "sprintf": "*"

    instead, it should be allowed to use the latest version of express 3.x.x as shown below:

    "name": "CustomerManager"
    , "version": "0.0.1"
    , "private": true
    , "dependencies": {
    "express": ">= 3.0.0"
    , "jade": ">= 0.0.1"
    , "mongodb": ">= 0.9.7-3-5"
    , "mongoose": ">= 2.4.10"
    , "connect-mongodb": ">= 1.1.3"
    , "sprintf": "*"

    Otherwise express throws an error and will not start the app.

    Now the question: You have defined two services the modalService and the dialogService. Of the two, it seems like only the modalService is being used in the application, correct? Why have you included the dialogService then? I am confused. kindly explain.



  • Hello,

    I have an error when I load AngularJSDemos with Visual Studio.

    Error 1

    The program d: \ TESTS ROAMING \ 2014 \ AngularJs Program \ AngularJSDemos \ AngularJSDemos \ obj \ x86 \ Debug \ WindowsApplication.exe 'does not contain a' Main 'method suitable for a static entry point D: \ TESTS ROAMING \ 2014 \ AngularJs Program \ AngularJSDemos \ AngularJSDemos \ CSC AngularJSDemos

    Ps help on this case.

Comments have been disabled for this content.