An Introduction To AngularJS

Article Primary image
Author Image - Phil Middlemass

By Phil Middlemass

Our Creative Director giving his opinion on 17 years in the digitial industry working with leading brands and companies

As one of Leighton's Web Developers, I'm involved in a variety of projects using numerous different tools and techniques. Throw in to this my passion for all things tech, I love to explore the latest industry trends, sharing my thoughts and insights regularly.

A couple of weeks ago I published the below post on my blog, delving in to the AngularJS framework, explaining exactly what it is and how it can be utilised.

Receiving a great response, it's led me to share it here on the Leighton blog, in an effort to spread the word about the many advantages AngularJS has to offer over the competition.

What is AngularJS?

AngularJS is an open-source Javascript framework developed and maintained by Google. Created in 2009, the first stable version was released in June 2012. Since then AngularJS has gained widespread popularity in the web development community and is now becoming the front-end framework of choice for many agencies.

Best suited to building single-page applications, it extends HTML's syntax with new attributes. Supported by all major browsers, AngularJS is a complete client-side solution written with testability in mind thanks to its use of dependency injection and decoupling of application logic from DOM manipulation.


¬

Core Concepts

This section provides an overview of the key components that make up the AngularJS framework, along with a number of interactive examples to show these in action.

Expressions

AngularJS is distributed as a Javascript file. To utilise the framework we need to include this on our webpage with a script tag and define our application with the data-ng-app directive.

The example below highlights how AngularJS enables you to execute expressions directly within your HTML code. Expressions are contained within {{ double braces }}, and their output is displayed inline on the page.

<!DOCTYPE html>
<html>
<head>
	<title>AngularJS Example 1</title>
</head>
<body>
	<div data-ng-app="">

		<p>{{ 2 + 3 }} passengers<p>

	</div>

	<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js"></script>
</body>
</html>

¬

This will output: {{ 2 + 3 }} passengers

¬


Moving on to a more interesting example of AngularJS expressions (this time using variables), we also introduce the data-ng-init directive which can be used to initialise application data.

Note: This is not the best way to create variables, but we'll get to that later in the article.

<!DOCTYPE html>
<html>
<head>
	<title>AngularJS Example 2</title>
</head>
<body>
	<div data-ng-app="" data-ng-init="adults = 2; children = 3">

		<p>{{ adults + children }} passengers<p>

	</div>

	<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js"></script>
</body>
</html>

¬This will also output: {{ adults + children }} passengers


Directives

AngularJS enhances HTML with a whole bunch of built-in directives that can be used to attach new behavior to a specified DOM element. Offering a high degree of flexibility, AngularJS even lets you build your own custom directives.

Note: AngularJS directives only require the ng- prefix but making use of the data- attribute will allow us to create valid HTML5.

This example introduces one of the most heavily used directives, data-ng-model which binds the value of a HTML control (such as an input or select field) to application data.

<!DOCTYPE html>
<html>
<head>
	<title>AngularJS Example 3</title>
</head>
<body>
	<div data-ng-app="" data-ng-init="adults = 2; children = 3">

		Adults: <input type="number" data-ng-model="adults" />
		Children: <input type="number" data-ng-model="children" />

		Total Passengers: <b>{{ adults + children }}</b>
	</div>

	<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js"></script>
</body>
</html>

Try modifying the input fields below to see this code in action.

Adults:
Children:

Total Passengers: {{ adults + children }}


Another important directive in AngularJS is data-ng-repeat which iterates through a collection of data, replicating the specified template.

The example below uses an array of flight objects to demonstrate how we can implement this.

<!DOCTYPE html>
<html>
<head>
	<title>AngularJS Example 4</title>
</head>
<body>
	<div data-ng-app="" data-ng-init="flights = 
		[{ name:'Mark', outbound:'Madrid', inbound:'London' },
		{ name:'Paul', outbound:'New York', inbound:'Manchester' },
		{ name:'Chris', outbound:'London', inbound:'Dubai' }]">
		
		<ul>
			<li data-ng-repeat="flight in flights">

				{{ flight.name }}: {{ flight.outbound }} - {{ flight.inbound }}

			</li>
		</ul>
	</div>

	<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js"></script>
</body>
</html>
This will output:
  • {{ flight.name }}: {{ flight.outbound }} - {{ flight.inbound }}

¬

Filters

AngularJS filters allow you to refine application data on the client-side without making a request to the server. As with directives, there are many built-in filters available but you can also create custom filters to meet your own specific needs.

This example filters our flight data based on input from the user, ordering these results by name. You will notice that we can chain multiple filters together using the | pipe | character, making this an extremely powerful feature within AngularJS.

<!DOCTYPE html>
<html>
<head>
	<title>AngularJS Example 5</title>
</head>
<body>
	<div data-ng-app="" data-ng-init="flights = 
		[{ name:'Mark', outbound:'Madrid', inbound:'London' },
		{ name:'Paul', outbound:'New York', inbound:'Manchester' },
		{ name:'Chris', outbound:'London', inbound:'Dubai' }]">

		Search: <input type="text" data-ng-model="filterFlights" />

		<ul>
			<li data-ng-repeat="flight in flights | filter:filterFlights | orderBy:'name'">

				{{ flight.name }}: {{ flight.outbound }} - {{ flight.inbound }}

			</li>
		</ul>
	</div>

	<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js"></script>
</body>
</html>

Use the search box below to filter the list of flights and see this code in action.

Search:

  • {{ flight.name }}: {{ flight.outbound }} - {{ flight.inbound }}

¬

Controllers

Whilst useful for our simple examples, using the¬data-ng-init¬†directive to create all of our application data would not be a very practical solution in a larger application. Fortunately AngularJS provides us with controllers to manage our data. These are defined using the data-ng-controller directive and can contain both properties and¬†methods.

Each controller has an associated $scope object in AngularJS. All child elements of the controller within the DOM can read and modify $scope and so we need to assign our properties and methods to this, as seen in the example below.

<!DOCTYPE html>
<html>
<head>
	<title>AngularJS Example 6</title>
</head>
<body>
	<div data-ng-app="" data-ng-controller="passengers">
 
		Adults: <input type="number" data-ng-model="adults" />
		Children: <input type="number" data-ng-model="children" />
 
		{{ totalPassengers() }}
	</div>

	<script>
		function passengers ($scope)
		{
			$scope.adults = 2;
			$scope.children = 3;

			$scope.totalPassengers = function ()
			{
				return "Total Passengers: " + ($scope.adults + $scope.children);
			}
		}
	</script>
 
	<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
</body>
</html>

Try modifying the input fields below to see this code in action.

Adults:
Children:

{{ totalPassengers() }}


¬

Modules

AngularJS modules declaratively specify how an application should be bootstrapped. You can think of them as a container for the different parts of your application.

It's recommended that you create a module for each individual feature or component in your application, along with an application-level module that depends on these and contains any initialisation code. Taking this approach helps make your code both reusable and testable.

In the interests of introducing one concept at a time, the previous examples haven't followed AngularJS best practices (due to omitting controllers and modules for instance). The example below pulls all these concepts together to demonstrate how a practical application should be structured.

The data-ng-app directive now specifies a root module for the application. Wanting to highlight how individual components of the application can be modularised, we have also added a custom directive. During the creation of the root module we specify the module containing this new directive as a dependency.

<!DOCTYPE html>
<html>
<head>
	<title>AngularJS Example 7</title>
</head>
<body>
	<div data-ng-app="myPassengerApp" data-ng-controller="passengers">
 
		Adults: <input type="number" data-ng-model="adults" />
		Children: <input type="number" data-ng-model="children" />
 
		<span data-total-passengers></span>
	</div>

	<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js"></script>

	<script>
		// create application-level module, specifying dependencies.
		angular.module ("myPassengerApp", ["totalPassengersDirective"])

			.controller ("passengers", function ($scope)
			{
				$scope.adults = 2;
				$scope.children = 3;
			});

		// create module containing custom directive (no dependencies).
		angular.module ("totalPassengersDirective", [])

			.directive ("totalPassengers", function ()
			{
				return
				{
					template: "Total Passengers: {{ adults + children }}"
				}
			});
	</script>
</body>
</html>

Try modifying the input fields below to see this code in action.

Adults:
Children:

¬


¬

Unit Testing

Unit testing deserves an article all of its own, but this covers the key points to get you started. The AngularJS development team have created Karma, an engine that runs unit tests against Javascript code (built specifically with AngularJS in mind). This is most commonly used with Jasmine, a testing framework for Javascript.

The example below demonstrates how to describe a test using Jasmine's behaviour-driven syntax, in this case simply checking the initial values of adults and children from our passengers controller.

describe ("unit testing passengers controller", function ()
{
	var scope, controller;

	// load module containing the passengers controller
	beforeEach (module ("myPassengerApp"));
  
	
	beforeEach (inject (function (_$rootScope_, _$controller_)
	{
		// create a scope object for us to use
		scope = _$rootScope_.$new();

		// create the controller
		controller = _$controller_("passengers", {
			$scope: scope
		});
	}));

	it ("should start with adults and children populated", function ()
	{
		// assert scope was correctly setup in beforeEach()
		expect(scope.adults).toEqual(2);
		expect(scope.children).toEqual(3);
	});
});

Please visit the Karma and Jasmine websites for a much more in-depth explanation on how to install, configure and use these tools to help create robust AngularJS applications.


¬

Summary

Here at Leighton we've incorporated AngularJS in to several projects, ranging from small internal tools to large applications for our global clients including British Airways. Unit testing plays a huge role in our development process, something which AngularJS excels in making it an obvious choice for us, but we've also seen significant benefits in the speed and flexibility of application development.

We have only scratched the surface of what the framework has to offer, but I hope this article has given you an insight in to how, why and when to use AngularJS.

Note: The first details of Angular 2.0 (due for release in late 2015 / early 2016) have been announced in the last few weeks. Click here if you'd like to read more about the future of Angular.


¬

Useful Links

angularjs.org - The official AngularJS website.

Code School - Code School have a free AngularJS course to get you started.

AngularJS Blog - Stay up to date with the latest news in the AngularJS community.

Built with AngularJS - This website showcases hundreds of applications and experiments built with AngularJS.

AngularJS Modules - Offers a collection of user-submitted modules to utilise in your applications.

YouTube - The AngularJS YouTube channel.

Comments