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:
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:
- Using factories and services as re-useable data services (see the app/services folder)
- Creating custom directives (see the app/directives folder)
- Custom paging (see app/views/customers/customers.html and app/controllers/customers/customersController.js)
- Custom filters (see app/filters)
- Showing custom modal dialogs with a re-useable service (see app/services/modalService.js)
- Making Ajax calls using a factory (see app/services/customersService.js)
- 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.
- Intercepting HTTP requests to display a custom overlay during Ajax calls (see app/directives/wcOverlay.js)
- Custom animations using the GreenSock library (see app/animations/listAnimations.js)
- Creating custom AngularJS animations using CSS (see Content/animations.css)
- Card View and List View display of data (see app/views/customers/customers.html and app/controllers/customers/customersController.js)
- Using AngularJS validation functionality (see app/views/customerEdit.html, app/controllers/customerEditController.js, and app/directives/wcUnique.js)
- Nesting controllers
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:
- 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.
- 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:
- The directives folder contains the custom directives created for the application.
- The filters folder contains the custom filters created for the application that filter city/state and product information.
- The partials folder contains partial views. This includes things like modal dialogs used in the application.
- 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.
- 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:
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:
- In the CustomerManager directory execute 'npm install' to install Express, MongoDB and Mongoose (package.json).
- 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:
- Start the Node/Express server by navigating to the CustomerManager/server directory and executing 'node app.js'
- View the application at http://localhost:3000 in your browser.
The Customer Manager application uses the following frameworks and libraries on the front-end:
- AngularJS (with the ngRoute and ngAnimation modules)
- Angular UI BootStrap
- 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.
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:
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.
Two custom directives are currently included in the application:
- 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.
- 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.
The application includes two custom filters used to filter data in the customers and orders views:
- Name/City/State Filter (app/filters/nameCityStateFilter.js)
- 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.