# Getting started with AngularJs
Published on 29-07-2015

Javascript is getting more popular now while it could be a nightmare to code it.  There is an uncontrollable growth in javascript frameworks to make your development progress easier so you can create code in less time. In this article I will explain how to start with AngularJs.

AngularJs

AngularJs is an open source javascript framework created by Google and is maintained by Google and the open community of individual developers. Check the wiki for more info about AngularJs.

The framework is user friendly to develop with and runs client side in the web browser. It also uses the MVC pattern so the presentation layer is separated with the data and logic.

 

Lets begin!

You have to run a webserver like Apache on your PC. There are easy all-in-one packages (for Windows) to setup apache like XAMPP or WAMP (I don't have to tell you that you must not use these webservers for production right? :)). Or you could use a nodejs webserver.

Create the index.html:

<!DOCTYPE html>
<html>
	<head>
		<title>Getting started with angular</title>
		<script src="/bower_components/angularjs/angular.min.js"></script>
		<script src="/js/app.js"></script>
		<script src="/js/controller.js"></script>
	</head>
	<body ng-app="angularApp" ng-controller="MainController">
	
	</body>
</html>

 

Create the js/app.js:

var angularApp = angular.module("angularApp", [
	"angularControllers"
]);

 

Create the js/controller.js:

var angularControllers = angular.module("angularControllers", []);

angularControllers.controller("MainController", function() {
	console.log("Main");
})

Well, this was quite easy huh? If you run this code, you have a single page with a controller. Let's add some pages and navigations.

There are two options for navigations: angular $route, and a commonly used third party library UI-router. If you wish to have a simple page navigation, then the build in angular $route is enough. If you want more advanced navigation with nested views and states, then use UI-router. In this example we will be using UI-router.

You will have to download the UI-router library and include it in index.html. I am using bower package management for my web libraries, even for angular.
Bower has also a dependency management system ex: if your fubar["1.2" ] library requires at least jQuery["1.10"], then fubar 1.2 will be installed with jQuery 1.10. Pretty cool huh? Take another coffee with the time you've saved!

Just take a look at it if you have time. For this example you could skip the bower part and just download UI-router library.

Include the angular-ui-router.min.js in index.html and add the <ui-view> directive inside the <body> tag.
index.html

<!DOCTYPE html>
<html>
    <head>
        <title>Getting started with angular</title>
        <script src="/bower_components/angularjs/angular.min.js"></script>
        <script src="/bower_components/angular-ui-router/release/angular-ui-router.min.js"></script>
        <script src="/js/app.js"></script>
        <script src="/js/controller.js"></script>
    </head>
    <body ng-app="angularApp" ng-controller="MainController">
        <ui-view>
        </ui-view>
    </body>
</html>

The <ui-view> directive decides that the content from the page states will be rendered here.

Inside your app.js we need to load the module "ui-router" and add the page states configuration.
js/app.js:

var angularApp = angular.module("angularApp", [
	"angularControllers",
	"ui.router"
]);

angularApp.config(function($stateProvider, $urlRouterProvider) {
	$stateProvider
	.state("homepageState", {
		url: "/home/",
		templateUrl: "templates/homePage.html",
		controller: "HomePageController"
	})
	.state("myOtherStateName", {
		url: "/secondPage/",
		templateUrl: "templates/secondPage.html",
		controller: "SecondPageController"
	});
	$urlRouterProvider.otherwise("/home/");
});

This still sounds easy right? Well, it is! We have done the following things:

  • Registered "ui-router" module to "angularApp".
  • Added a config block where the "ui-router" module is configured.
  • Added two states named "homepageState" and "myOtherStateName"
  • Added a fallback state to url: "/home/". You could define a 404 page like "templates/pagenotfound.html".

Every state has his state name(we will come back later to this), an URL to map the browser URL, and a controller. There are more advanced options. Check the ui-router wiki. You could even delay the page navigation. state loading until some requested remote data is loaded, but that's out of the scope for this article.

In this example we will be using a basic page with an controller behind it.

js/controllers.js

var angularControllers = angular.module("angularControllers", []);

angularControllers.controller("MainController", function($scope) {
	$scope.callTheMain = function() {
		console.log("What's up?!");
	}
});
angularControllers.controller("HomePageController", function($scope) {
	$scope.callTheMain();
	$scope.title = "This is the homepage";
});
angularControllers.controller("SecondPageController", function($scope) {
	$scope.title = "The secondpage";
});

Angular controllers supports inheritance. In index.html there is the <body ng-controller="MainController">. Every controller inside <body> inherits "MainController". In this case if the current state is "homepageState", we have a controller named "HomePageController" who automatically inherits"MainController". 

So basically like this:

<div ng-controller="ParentController">
        <div ng-controller="SomeChildController"></div>
</div>

"SomeChildController" can call "ParentController" but "ParentController" cannot access "SomeChildController"

 

Lets create the state templates

templates/homePage.html

<div>{{title}}</div>
<br />
<div>Go to the <a ui-sref="myOtherStateName">next</a> page.</div>

templates/secondPage.html

<div>{{title}}</div>
<br />
<div>Go back to home <a href="#/home/">page</a>.</div>
<br />
<label>Modify the title!</label>
<input type="text" ng-model="title"/>

You should have noticed the two difference in the templates. In homePage.html we use the ui-sref="myOtherStateName" to create a link to secondPage.html. This is the proper way to create links to different states. So if you want to change the URL's to these states, you only have to change the url property in app.js. 

The ui-sref also works on other html tags like <div ui-sref="myOtherStateName">link</div>. 

In secondPage.html we have used the plain <a> which is self explanatory.

 

Template compilation

Both templates contain {{title}} expression. Angular compiles the template and replaces the {{title}} expression with the value of $scope.title from the controller. This also could be a function call :{{getTitle()}}.

AngularJS provides two-way databinding support. If you write text in the input field in secondPage.html, the value in $scope.title changes synchronously.

 

So far so good, we have an AngularJS application with page navigation. Lets see what we can do with services and factories

Create js/services.js

var angularServices = angular.module("angularServices", []);

angularServices.service("MyService", function() {
	this.helloWorldMe = function(myName) {
		return "Hello world " + myName;
	}
});

angularServices.factory("PetFactory", function() {
	return {
		createPet: function(myPetName) {
			return "Oh hello " + myPetName + "!";
		}
	}
});

The main difference between a service and a factory is explained in this thread on StackOverflow.

Summarized:

  • A service is a singleton. This means that there is only one instance of this service.
  • A factory returns a new object.

 

Add the services module to your app like you did before:

js/app.js

​var angularApp = angular.module("angularApp", [
	"angularControllers",
	"angularServices",
	"ui.router"
]);

angularApp.config(function($stateProvider, $urlRouterProvider) {
	$stateProvider
	.state("homepageState", {
		url: "/home/",
		controller: "HomeController",
		templateUrl: "templates/homePage.html",
		controller: "HomePageController"
	})
	.state("myOtherStateName", {
		url: "/secondPage/",
		templateUrl: "templates/secondPage.html",
		controller: "SecondPageController"
	});
	$urlRouterProvider.otherwise("/home/");
});

 

Add the service "MyService" and factory "PetFactory" into our controllers and execute the functions.

js/controllers.js

var angularControllers = angular.module("angularControllers", []);

angularControllers.controller("MainController", function($scope) {
	$scope.callTheMain = function() {
		console.log("What's up?!");
	}
});
angularControllers.controller("HomePageController", function($scope, MyService) {
	$scope.callTheMain();
	$scope.title = "This is the homepage";
	
	console.log(MyService.helloWorldMe("Gokhan"));
});
angularControllers.controller("SecondPageController", function($scope, PetFactory) {
	$scope.title = "The secondpage";
	
	console.log(PetFactory.createPet("Bob"));
});

Now you can reuse your code by using services and factories.
I will post more articles about filters and directives.

 

Download the complete project with all files here