Understanding AngularJS – Simple Example

I did a similar post as this post for Backbone.js Understanding Backbone.js – Simple Example. Based on readers’ comments the backbone.js post seemed to assist many people. My goal with this post is to help others understand the core parts of AngularJS and how they work together.

The AngularJS application that we are building will display a list of movies and will have the ability to add movies. We could create this application with very minimum code, but extensibility and maintainability will be limited. My primary objective is to show how to structure an AngularJS application that provides a base of knowledge to create other AngularJS applications extensible and maintainable.

My target audience will have some knowledge about AngularJS, but are having a difficult time implementing all but the most basic applications. By simple, I mean you should only have to focus on AngularJS. We will not be using jQuery, Twitter Bootstrap, or other 3rd party libraries.

We could create this application with just a controller and a view. But in this post I will describe the following core AngularJS features:

  • Routes
  • Modules
  • Views
  • Controllers
  • Services

Above I mentioned I will keep this post simple, but we do need a web server. The AngularJS Theater application will load views and data (json files) from the server. I would like to do these examples by access “file:///E:/TempProjects/Theater/index.html#/” on local computer, but most browsers cannot access these files on local computer do to Cross Origin issues. Here a StackOverflow question and answer that describes this issue: Cross origin requests are only supported for HTTP but it’s not cross-domain. So we need a web server. Any web server will do, such as IIS, Node.js and Express or other server. In this example I will be using Node.js and Express. You will not need to know anything about Node.js; all that is need is for you to install Node.js and to execute a script that I will provide. I will step you through the complete process to get Node.js and Express up and running.

Google Chome will be the browser I use, but any current browser should work fine. The reason I pick Chome is for its development tools. I will be developing in JetBrains WebStorm IDE, but any IDE or text editor should be fine.

This post will be based on a contrived idea of displaying a list of movies at a theater. There is nothing fancy here.

The complete solution can be downloaded from here:
Source – Understand-AngularJS-Simple Example(Theater)

Based on comments from Hasan this example works with AngularJS 1.1.5. It does not work with AngularJS 1.2.3.

1. Theater Application Location

First we need to identify the location for the AngularJS Theater application. All of my files will be located in a directory called “Theater” and will be located at “E:TempProjectsTheater”. The path doesn’t matter, so feel free to locate the Theater directory wherever is best for you.

Here’s the original structure of the application. To start out, there will be one directory call “js”. The “js” directory will contain all of our client side JavaScript. This director will include 4 directories (controller, data, services, views). Go ahead and create this directory structure.

Also create the index.html file. Add the following HTML to the index.html file

2. Installing Node.js

We need a Web Server to display the HTML file we just created. So here is where we will setup Node.js and Express. Node.js is a framework and Express provides a web server.

The web server we need does not need to do anything fancy. The only feature that the web server needs is the ability to provide static files.

To get started download and install Node.JS: http://nodejs.org/

After you navigate to www.nodejs.org click the install button. Node.js website is smart enough to detect the type of operating system you are running and will down the appropriate version of Node.js. Once Node.js download is complete, run the install. There isn’t anything special in the install; you should have no need of changing anything during the install wizard process.

Lets now test that Node.js was installed correctly. Open a Windows Command Prompt and enter “Node” and [enter]. You should be prompted with a “>”. Now enter “2 + 2” and [enter]. Node should return 4. Nothing really cool, but we have confirmed that Node.js has been installed correctly.

To exit Node, enter [ctrl]+C twice

Great! Node.js has been installed

3. Install Express

Express is a package that execute within Node.js. To install express, in the Command Prompt navigate to your directory for the Theater application. For me the path is “E:TempProjectTheater”.

Now lets install Express as a package for Node.js. At the command prompt type “npm install express”“npm install express@3.4.6”.
(update: The new version of express 4.0 has breaking changes from the previous major version 3.x.x. This is the simplest solution. The other solution is to change the server.js file. To change the server.js file see: http://stackoverflow.com/questions/22265143/typeerror-object-function-req-res-next-app-handlereq-res-next-has/23317325#23317325)

That installed Express and should have created a directory called “node_modules”. The directory that was created isn’t important, but I wanted to let you know just in case you saw this directory and wondered what it was.

4. Configure Express

Now that Express is installed, we need to configure it to execute as a webserver. Create another file in the Theater directory call “server.js”.

Add the following code to the “server.js” file.

We will need to run this code in Node.js.

5. Start Express Web Server in Node.js

Now we need to start the Express web server and point it to our Theater application.

In the Command Prompt confirm you are at the Theater directory.

(For the image above disregard the “01” in the file path; I’m using this number to help me manage all the code I’m creating)

Once you have confirmed the path is correct, enter “node server.js 8000” and press [enter].

Now the web server should be running on port 8000 and should be pointing to you Theater application.

Lets confirm that the web server is running and that our Theater application can be access through a browser.

Open up your browser of choice and navigate to “localhost:8000”. I’m using Google Chrome as my browser.

If everything has been done correctly up to this point the index.html page should be displayed in the browser.

6. The End Goal

To get to this point we had to accomplish many steps, but now we can focus on writing the AngularJS Theater application.

Here’s the end goal for our application. This application will display a list of movies and will allow the user to add a movie.

From this point on I will only focus on AngularJS and the ancillary technologies (JavaScript and HTML). I do not want to complicate anything.

(Example of the finish system)

7. Application Structure

We want to create a modular application. The diagram below depicts how each component integrates with other components. Here are the steps that occur for the Angular application to run.

  1. Web page loads
  2. Web page loads the application module
  3. The module is configured with routes
  4. The routes execute and loads the View and the Controller
  5. Services are created and injected into the Controller
  6. The view is added to the web page
  7. The scope is bound to the view and the Controller

We will work through each of these steps.

8. The Web Page

The initial web page (index.html) is where the application starts. This is where we load AngularJS, tell the page to load the “theaterApp” app module, and identify where the view should be displayed.

Change the index.html file to match the following code.

In this webpage the first thing that occurs is that Angular.js JavaScript gets loaded. Once the Angular.js file is loaded it parses the DOM looking for AngularJS directives, such as ng-app and ng-view. ng-app=”theaterApp” tells AngularJS to load the “theaterApp” module. The “theaterApp” module has not been created yet; we will do this next when we create the file “theaterApp.js”.

The ng-view is a placeholder for where the view should be inserted. The view that will be used will be identified in the route. We will create the view later.

Instead of downloading AngularJS library we will reference it through CDN (content delivery network). I will give you the responsibility to lookup the benefits of using a CDN.

If refresh the webpage, we should get an error identifying that the theaterApp.js cannot be found. This is expected.

Lets go create the theaterApp.js file and the module.

9. Modules

Modules are used to configure AngularJS applications. In our Theater application we will use module to configure routes. In this application we will have one route, but in more complex applications you could have many routes.

In the following code snippet we created a module called theaterApp and assigned the module to a variable called theaterApp. The module name and variable can be different, but to keep things from getting confusing I recommend these names stay the same.

If the application had dependencies on other modules we would add them to the array. Since this application does not have any dependencies the array is empty.

In the “js” director create a new file called “theaterApp.js” and add the following code.

Your files structure should look like this. We don’t have a lot of code to write and we could put all the JavaScript code in one file, but for this post I want to show one possible structure for organizing your code. In a real application you will probably have multiple controllers, services, and views. I believe it’s better to separate these into their own directories.

10. Routing

We are using routing to identify what controller and view should be loaded and displayed. The routing configuration will be added to the theaterApp.js file

We will make configuration changes to theaterApp module. We use dependency injection to load the AngularJS $routeProvider service.

When the user navigates to the root of the page (“/”, localhost:8000/ or localhost:8000/index.html) the code will load the controller called MoviesCtrl and the template (ie view) at the location “js/views/moviesView.html”. We haven’t created the MoviesCtrl or the view yet.

If the first route is not matched then the second route ($routeProvider.otherwised({redirectTo”: “/”});) with the method otherwise will catch all other request. This route is used to redirect everything back to the root route “/”.

Add the following code to the theaterApp.js

If we run the web page we should get an error that the moviesView.html cannot be found

11. Data

Before we create the view I would like to discuss data.

The view and controller will reference movies data in json format, so it a good idea to understand the data now. The data in the file is an array of movies. We will only reference the name value for each movie. This file can be located here: Theater JSON Data

12. View

The view is the temple where data will be merged and displayed. AngularJS will insert the view into the index.html page were ng-view directive was identified.

The view will be used to display each movie in an array. ng-repeat is an AngularJS directive that is used to loop through an array. The template includes the element where the ng-repeat directive is located. For our example, ng-repeat is used to iterate through each item in the movies array. For each iteration the item of the array will be assigned to the variable movie and a copy of template is created with the scope of the current movie. The template includes the <div> where ng-repeat is declared and all child nodes. For us our template is simple, but templates can be as complicate as you like.

The application will not work due to the state that it’s currently in. Below is an example of the results for ng-repeat if everything was wired up. Just to reiterate, this is an example if everything was working.

If we actually run the web page we should get an error that the MoviesCtrl is not a function. Remember in theaterApp.js file we create a route that links the view to a controller; the controller has not been created yet. We will create the MoviesCtrl next.

13. Controller

Based on AngularJS documentation, there are two primary responsibilities for the controller:

  • Set up the initial state of a scope object
  • Add behavior to the scope object

In this part of the tutorial we will set up the initial state of our scope object. Later in the post we will add behavior to the scope object so that we can add movies.

First create a new file called moviesCtrl.js in the directory call controllers.

In the first line of code, we tell the theaterApp that we want to create new controller called “MoviesCtrl” and to inject the $scope object.

Then we create a model that is static array of movies. And, then we assign that static array of movies to the $scope.movies object.

This will only display two movies. Latter in the post we will work through a couple additional steps to use HTTP request to retrieve the movies from the server.

You need to be aware that the model is not the scope. The scope contains the model.

One last thing to do, in index.html add a script reference to the moviesCtrl.js file

14. View in Browser

Now if we view the website in the browser a list that includes 2 movies should be displayed.

15. Retrieve Data from Server

Usually data would not be hard coded into the controller. Since we have a web server, lets retrieve the data from the server.

If you have not added the file movies.json to the project, add the movies.json file to the directory “js/data”. You can copy and paste the data from Section 11 (Data) to this file. If everything is setup correctly, you should be able to navigate to the movies.json file in your browser by using this URL: http://localhost:8000/js/data/movies.json

In the MoviesCtrl.js file remove all the code except where we declared the controller.

In the first function declaration add $http parameter. AngularJS dependency injection will provide the $http automatically. We will use the $http service to retrieve data from the server.

On the next line we use $http.get to retrieve data from the movies.json file. This will do an HTTP GET request to the server. The application doesn’t realize we are retrieve data from a file, all the application is aware of is that there is a GET request and data is being returned in the JSON format. We could be doing a REST call here.

The $http.get() function is asynchronous. AngularJS uses promises for results of asynchronous operations. Once the request is sent to the server the browser is allowed to do other tasks. Once the response is returned to the server, the .then callback is executed. The .then callback is executed only when the response is returned. If the server takes 10 seconds to return a response, the browser will not be frozen since the request is run asynchronously. After the response is returned, even if it took 10 seconds, the .then callback is executed.

The get.then has the following signature get.then(success, error). This is true for promises in general. The results of the response are also available here in the success and error callback. For a successfully request and response, the data retrieved from the server can be access through results.data. If the request is not successful the error function will be called. A description of the error can be retrieved from results.data.

Here a great explanation of Angular.js Promises Angular.js Promise and Deferred Api – Implementation Explained.

If our code returns a successfully response, the results.data should contain the movies array and is assigned to $scope.movies objects.

The MoviesCtrl.js file should look like the following.

Now refresh the page in your browser. The application should now retrieve all the movie data from the server and display it in the browser.

16. Add a Movie

Lets add a movie to the list. We won’t update the data on the server; that would require us to change the web server code. So will update the movies data in the $scope.

We will need to make changes in two different files, the movieCtrl.js and the moviesView.html. It doesn’t matter which order we make the changes. For more robust application the developer could change the movieCtrl.js file and a designer could change moviesView.html files in parallel

Since I’m a developer we will make the needed changes to the movieCtrl.js first.

Previously I mentioned that controls have two primary purposes:

  • Set up the initial state of a scope object
  • Add behavior to the scope object

We have already set the initial state of the scope object; now we will add behavior to add a new movie to the scope object.

In the movieCtrl.js file add a addNewMovie function to the $scope object. This function accepts an argument of movieName.

From the movie name create a new movie object.

By using splice, add the new movie to the movies array in the $scope object. Splice allows us to add the movie to the beginning of the array.

Now lets change the moviesView.html so that the user can add a movie.

In the view we need to add an input textbox and a button.

Create an input textbox and add the AngularJS ng-model directive. Assign the ng-model directive to “newMovie.name”. What is actually happening here is newMovie.name is being bound to the $scope. Now the $scope has the following structure:

  • $scope.movies
  • $scope.newMovie
  • $scope.addNewMovie()

This structure can be reference in the view or the controller.

Now add a button with the AngularJS ng-click directive. Assign the ng-click directive to “addNewMovie(newMovie.name)”. Remember that in the controller we add a function to the $scope called addNewMovie. The code in ng-click can be thought as $scope.addNewMovie($scope.newMovie.name). Since a view can only be bound to one scope, we don’t need to identify the scope in the view.

View the web page in the browser and refresh. Enter a new movie name and click the “Add” button. The new movie is added to the $scope.movies array and is displayed in view. This is very cool. Very little code was needed to add this functionality.

17. Services – Getting the Data

I could just end the post here, but I believe understanding services is extremely important.

Scott Allen did an amazon job discussing services in AngularJS in his post AngularJS Abstractions: Services. In Scott’s post he mentions,

“AngularJS will manage services to make sure there is only one instance of a service per application. This makes services a convenient storage location for data that needs to stick around (controllers and their models can come and go as views are loaded and unloaded in the DOM).”

We are going to create a service called movieService. Most of the functionality in the MoviesCtrl.js will be move to the movieService.js file.

Create a file in the “service” directory called movie.Service.js.

There’s multiple ways to declare a service. We will use the factory method. Using the theaterApp.factory method create a service called “moviesService”. Use dependency injection to pass in the $http service.

We need a place to store the movies. Create a private variable called _movies and assign it to an empty array.

We need a function that will retrieve the movies from the server. Create a private function call _getMovies. We will remove code from movieCtrl.js file that retrieves movies from the server and put it in this new _getMovies function.

The calling will need to access the service. Let’s create the interface for the service. Create an object literal that returns the _movies array and the _getMovies object.

If you refresh the application in your browser the movies should display, but the functionality to add a movie will not work.

18. Services – Add New Movie

The moviesService should manage all the CRUD functionality for movies. This includes adding, deleting and possibly editing. For us, we are only concern with reading and adding. I will let you add the other functionality.

In the service create a new private function called _addNewMovie. This function should accept an attribute of movie. In the function add the movie to the beginning of the _movies array by using splice.

In moviesService interface (the return statement) add addNewMovie that returns the _addNewMovie function.

Important, in index.html Add a script reference to moviesServcie.js file.

19. Change Controller to use Service

The moviesCtrl does not need to access the server directory. Since we create a service for retrieving data from the server; we should use it.

In the MoviesCtrl, remove the $http and replace it with the moviesService. Now the controller will use dependency injection to include the moviesService in the controller.

The controller will reference the movies in the service. Assign the $scope.movies to the moviesService.movies.

When the controller starts, the movies need to be retrieved data from the server by using the new service. On the service, call getMovies().

Instead of adding a new movie to the $scope directly, we will used the movieService to add the movie. In the addNewMovie function replace the splice function with a call to the movieServer.AddNewMovie function.

20. Finish

If you refresh the browser everything should be working now.

Final thoughts

I know this was a long post, but I want to explain a better structure that could be used to create AngularJS application. This is by no means perfect, but I believe it should get you started moving in the correct direction.

34 thoughts on “Understanding AngularJS – Simple Example”

  1. At last an example that steps through in a simple and understandable way.
    I was looking for an http example, this was exactly what I needed.

  2. It was nice article, thanks for collating everything at one place. One correction to install express below is the command

    npm install -g express

  3. Thoroughly enjoyed the Tut but am frustrated after a couple of weeks trying to repeat a cut-down version to exercise downloading a small json file using Dan Wahlin’s data (
    {firstName: ‘John’, lastName: ‘Doe’, address: {city: ‘Chandler’, state: ‘AZ’, zip: 85248}},
    {firstName: ‘Jane’, lastName: ‘Doe’, address: {city: ‘Chandler’, state: ‘AZ’, zip: 85248}},
    {firstName: ‘Johnny’, lastName: ‘Doe’, address: {city: ‘Phoenix’, state: ‘AZ’, zip: 85003}}
    ) and display it in a table using $scope – it works OK with static data but not with a Get.
    Using $http.get(“/serverData/myData.json”) .then(function (results) { …}, function (results) { …} and also tried the other version with
    var futResp = $http.get(‘/serverData/myData.json’);
    futResp.success(function(data) { … } and
    futResp.error(function(data) { …. }

    Tried both Web Matrix and Visual Studio windows dev environments (with IIS) and always see in Google Chrome; controller get error; status undefined Results: Syntax Error Unexpected Token f

    Now run out out of ideas so any suggestions on a way-ahead most gratefully appreciated.

  4. Ref previous comment – turned out to be incorrect formatting of the json file. Every field except numerics had to have double quotes –

    { “firstName”: “John”, “lastName”: “Doe”, “address”: { “city”: “Chandler”, “state”: “AZ”, “zip”: 85248} },
    { “firstName”: “Jane”, “lastName”: “Doe”, “address”: { “city”: “Sheriden”, “state”: “WY”, “zip”: 85248} },
    { “firstName”: “Johnny”, “lastName”: “Doe”, “address”: {“city”: “SLC”, “state”: “UT”, “zip”: 85003} }
    Another lesson learned – trust it may help someone!

  5. Fine tutorials.
    Why didnt you use ng-controller anywhere? Supposing more than one DOM in an .html view needs controllers, how will you specify them?

  6. Sorry about that . I meant why you need to add the script
    If there are more than one controller, then do you need to define each of them in a script src=”…” /script tag?

    1. The controller is defined in the moviesCtrl.js file, so the browser will need to load that JavaScript file.

      Yes, if there are more then one controller and the controller is in a different file, then you will need to include the additional file in a script tag.

  7. Thanks for those replies , Bardev. Its getting clearer.
    Is it possible to load different views(partials) onto multiple ng-views in the same shell page? Can you please give an example?

  8. Hi..
    The app worked very fine with Angular 1.1.5 mentioned here,,, but did not work with the latest edition Angular 1.2.3 🙁

  9. Can you please show how to access a database , say Oracle, from AngularJS? Do you need to have sever side tech like PHP/.NET for accessing database?

    1. To access a typical database (SQL Server, Oracle and etc) on the server you will typically need an API on the server side. If your doing .NET I recommend WebAPI on the server which provides a rest interface. I can’t speak for PHP.

      A NOSQL solution that has a rest interface built in is MongoDB.

  10. To make this work in later versions of Angular you need to load ngRoute.
    In the Index.html file change the script tags to the latest version of angular and also include the

    Then load ngRoute into the theaterApp by changing the first line of theaterApp.js to;
    var theaterApp = angular.module(“theaterApp”, [‘ngRoute’]);

    Nice tutorial. HTH.


  11. The Angularjs docs site should have this article along with big bold letters saying Read This First. Great job, sorting out many things for me after a week or two of trying to learn Angular and Js all in one go.

  12. When trying to configure express and using your script, I got the following error executing “node server.js 8000″:

    app.configure(function () {
    TypeError: Object function (req, res, next) {
    app.handle(req, res, next);
    } has no method ‘configure’
    at Object. (/home/nathaniel/workspace/WebServer/Theater/server.js:5:5)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:902:3

    So I took out the app.configure(function{…}); and the following script worked fine.:

    var express = require(‘express’);
    var app = express();
    port = process.argv[2] || 8000;

    “/”, //the URL throught which you want to access to you static content
    express.static(__dirname) //where your static content is located in your filesystem

    app.listen(port); //the port you want to use
    console.log(“Express server running at => http://localhost:” + port + “/nCTRL + C to shutdown”);

    1. The new version of express 4.0 has breaking changes from the previous major version 3.x.x. There are two ways to fix this.
      1) Install a specific version of express using this command “npm install express@3.4.6”
      2) Change the server.js file so that it’s compatible with express 4.0. Here’s an answer I provided on StackOverflow http://stackoverflow.com/a/23317325/92166 that shows how to do this.

      If I get time I will update the blog post to reference the express 4.0 version

  13. Nice tutorial
    to run with AngularJS v1.2.19 you need include angular-route.js
    and you have to change TheaterApp.js var theaterApp = angular.module(“theaterApp”, [‘ngRoute’])

    1. https://docs.angularjs.org/guide/providers
      “The most verbose, but also the most comprehensive one is a Provider recipe. The remaining four recipe types — Value, Factory, Service and Constant — are just syntactic sugar on top of a provider recipe.”

      When choosing between service and factory recipe, I usually default to factory recipe. The factory recipe seems more natural to me.

      If I need to configure the service during startup, the provider recipe is necessary.

  14. the code doesn’t throw error but draws blank. i tried copying it from the git too without luck. where is the ‘angular-route.js’ file that some people have mentioned?

Leave a Reply

Your email address will not be published. Required fields are marked *