AngularJS Service / Factory Tutorial with Example

angularjs service

1. Introduction to AngularJS Services

In AngularJS world, the services are singleton objects or functions that carry out specific tasks. It holds some business logic. Separation of concern is at the heart while designing an AngularJS application. Your controller must be responsible for binding model data to views using $scope. It does not contain logic to fetch the data or manipulating it.

For that we must create singleton objects called services. AngularJS can manage these service objects. Wherever we want to use the service, we just have to specify its name and AngularJS auto-magically inject these objects (more on this later).

Thus service is a stateless object that contains some useful functions. These functions can be called from anywhere; Controllers, Directive, Filters etc. Thus we can divide our application in logical units. The business logic or logic to call HTTP url to fetch data from server can be put within a service object.

Putting business and other logic within services has many advantages. First it fulfills the principle of separation of concern or segregation of duties. Each component is responsible for its own work making application more manageable. Second this way each component can be more testable. AngularJS provides first class support for unit testing. Thus we can quickly write tests for our services making them robust and less error prone.

angularjs service diagram

Consider above diagram. Here we divide our application in two controllers: 1. Profile and 2. Dashboard. Each of these controllers require certain user data from server. Thus instead of repeating the logic to fetch data from server in each controller, we create a User service which hides the complexity. AngularJS automatically inject User service in both Profile and Dashboard controller. Thus our application becomes for modular and testable.

2. AngularJS internal services

AngularJS internally provides many services that we can use in our application. $http is one example (Note: All angularjs internal services starts with $ sign). There are other useful services such as $route, $window, $location etc.

These services can be used within any Controller by just declaring them as dependencies. For example:

module.controller('FooController', function($http){
	//...
});

module.controller('BarController', function($window){
	//...
});

3. AngularJS custom services

We can define our own custom services in angular js app and use them wherever required.

There are several ways to declare angularjs service within application. Following are two simple ways:

var module = angular.module('myapp', []);

module.service('userService', function(){
	this.users = ['John', 'James', 'Jake'];
});

or we can use factory method

module.factory('userService', function(){
	
	var fac = {};
	
	fac.users = ['John', 'James', 'Jake']; 
	
	return fac;

});

Both of the ways of defining a service function/object are valid. We will shortly see the difference between factory() and service() method. For now just keep in mind that both these apis defines a singleton service object that can be used within any controller, filter, directive etc.

4. AngularJS Service vs Factory

AngularJS services as already seen earlier are singleton objects. These objects are application wide. Thus a service object once created can be used within any other services or controllers etc.

We saw there are two ways (actually four, but for sake of simplicity lets focus on 2 ways that are widely used) of defining an angularjs service. Using module.factory and module.service.

module.service( 'serviceName', function );

module.factory( 'factoryName', function );

When declaring serviceName as an injectable argument you will be provided with an instance of the function. In other words new FunctionYouPassedToService(). This object instance becomes the service object that AngularJS registers and injects later to other services / controllers if required.

When declaring factoryName as an injectable argument you will be provided with the value that is returned by invoking the function reference passed to module.factory.

In below example we define MyService in two different ways. Note how in .service we create service methods using this.methodname. In .factory we created a factory object and assigned the methods to it.

AngularJS .service

module.service('MyService', function() {
	this.method1 = function() {
			//..
		}

	this.method2 = function() {
			//..
		}
});

AngularJS .factory

module.factory('MyService', function() {
	
	var factory = {}; 

	factory.method1 = function() {
			//..
		}

	factory.method2 = function() {
			//..
		}

	return factory;
});

5. Injecting dependencies in services

Angularjs provides out of the box support for dependency management.

In general the wikipedia definition of dependency injection is:

Dependency injection is a software design pattern that allows the removal of hard-coded dependencies and makes it possible to change them, whether at run-time or compile-time. …

We already saw in previous tutorials how to use angularjs dependency management and inject dependencies in controllers. We injected $scope object in our controller class.

Dependency injection mainly reduces the tight coupling of code and create modular code that is more maintainable and testable. AngularJS services are the objects that can be injected in any other Angular construct (like controller, filter, directive etc). You can define a service which does certain tasks and inject it wherever you want. In that way you are sure your tested service code works without any glitch.

Like it is possible to inject service object into other angular constructs, you can also inject other objects into service object. One service might be dependence on another.

Let us consider an example where we use dependency injection between different services and controller. For this demo let us create a small calculator app that does two things: squares and cubes. We will create following entities in AngularJS:

  1. MathService – A simple custom angular service that has 4 methods: add, subtract, multiply and divide. We will only use multiply in our example.
  2. CalculatorService – A simple custom angular service that has 2 methods: square and cube. This service has dependency on MathService and it uses MathService.multiply method to do its work.
  3. CalculatorController – This is a simple controller that handler user interactions. For UI we have one textbox to take a number from user and two buttons; one to square another to multiply.

Below is the code:

5.1 The HTML

<div ng-app="app">
    <div ng-controller="CalculatorController">
        Enter a number:
        <input type="number" ng-model="number" />
        <button ng-click="doSquare()">X<sup>2</sup></button>
        <button ng-click="doCube()">X<sup>3</sup></button>
        
        <div>Answer: {{answer}}</div>
    </div>
</div>

5.2 The JavaScript

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

app.service('MathService', function() {
    this.add = function(a, b) { return a + b };
    
    this.subtract = function(a, b) { return a - b };
    
    this.multiply = function(a, b) { return a * b };
    
    this.divide = function(a, b) { return a / b };
});

app.service('CalculatorService', function(MathService){
    
    this.square = function(a) { return MathService.multiply(a,a); };
    this.cube = function(a) { return MathService.multiply(a, MathService.multiply(a,a)); };

});

app.controller('CalculatorController', function($scope, CalculatorService) {

    $scope.doSquare = function() {
        $scope.answer = CalculatorService.square($scope.number);
    }

    $scope.doCube = function() {
        $scope.answer = CalculatorService.cube($scope.number);
    }
});

5.3 Online Demo

Thus in the above angularjs injected service object to another service and in turn injected final service object to the controller object. You can inject same service object in multiple controllers. As angularjs service object is inheritedly singleton. Thus only one service object will be created per application.

6. End to End application using AngularJS Service

Let us apply the knowledge that we acquired so far and create a ContactManager application. This is the same app that we built-in our last tutorial. We will add a service to it and see how we can divide the code between service and controllers. Following are some basic requirements of this application:

  1. User can add new contact (name, email address and phone number)
  2. List of contacts should be shown
  3. User can delete any contact from contact list
  4. User can edit any contact from contact list

Following is the HTML code which defines a FORM to save new contact and edit contact. And also it defines a table where contacts can be viewed.

6.1 The HTML

<div ng-controller="ContactController">
    <form>
    <label>Name</label> 
        <input type="text" name="name" ng-model="newcontact.name"/>
    <label>Email</label> 
        <input type="text" name="email" ng-model="newcontact.email"/>
    <label>Phone</label> 
        <input type="text" name="phone" ng-model="newcontact.phone"/>
        <br/>
        <input type="hidden" ng-model="newcontact.id" />
     <input type="button" value="Save" ng-click="saveContact()" />
    </form>
<table>
<thead> 
<tr>
    <th>Name</th>
    <th>Email</th>
    <th>Phone</th>
    <th>Action</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="contact in contacts">
    <td>{{ contact.name }}</td>
    <td>{{ contact.email }}</td>
    <td>{{ contact.phone }}</td>
    <td>
        <a  href="#" ng-click="edit(contact.id)">edit</a> | 
        <a href="#" ng-click="delete(contact.id)">delete</a>
    </td>
 </tr>
</tbody>
</table>    
</div>

Next we add the AngularJS code to and life to our ContactManager appllication. We define a module ‘app’. This module is then used to create Service and Controller.

See in below code how ContactService is created. It has simple methods to save/delete/get the contact.

Note how the service object in injected in controller.

6.2 The JavaScript


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

module.service('ContactService', function () {
    //to create unique contact id
    var uid = 1;
    
    //contacts array to hold list of all contacts
    var contacts = [{
        id: 0,
        'name': 'Viral',
            'email': 'hello@gmail.com',
            'phone': '123-2343-44'
    }];
    
    //save method create a new contact if not already exists
    //else update the existing object
    this.save = function (contact) {
        if (contact.id == null) {
            //if this is new contact, add it in contacts array
            contact.id = uid++;
            contacts.push(contact);
        } else {
            //for existing contact, find this contact using id
            //and update it.
            for (i in contacts) {
                if (contacts[i].id == contact.id) {
                    contacts[i] = contact;
                }
            }
        }

    }

    //simply search contacts list for given id
    //and returns the contact object if found
    this.get = function (id) {
        for (i in contacts) {
            if (contacts[i].id == id) {
                return contacts[i];
            }
        }

    }
    
    //iterate through contacts list and delete 
    //contact if found
    this.delete = function (id) {
        for (i in contacts) {
            if (contacts[i].id == id) {
                contacts.splice(i, 1);
            }
        }
    }

    //simply returns the contacts list
    this.list = function () {
        return contacts;
    }
});

module.controller('ContactController', function ($scope, ContactService) {

    $scope.contacts = ContactService.list();

    $scope.saveContact = function () {
        ContactService.save($scope.newcontact);
        $scope.newcontact = {};
    }


    $scope.delete = function (id) {

        ContactService.delete(id);
        if ($scope.newcontact.id == id) $scope.newcontact = {};
    }


    $scope.edit = function (id) {
        $scope.newcontact = angular.copy(ContactService.get(id));
    }
})

6.3 Online Demo

That’s All Folks

We saw that angularjs service/factory objects are. How to define our own custom service/factory object in angularjs. Also we saw how dependency injection works. In the end we created a simply calculator application that wrap up all the concepts.

I hope you liked this tutorial. Feel free to post your comment below.

In this ongoing series, I will try to publish more AngularJS articles on topics like angularjs $http service, AngularJS filters, AngularJS directives etc.

References

Get our Articles via Email. Enter your email address.

You may also like...

108 Comments

  1. A.Lepe says:

    Your tutorials on AngularJS helped me to startup with it (looking forward for more of this serie!). I wish they were included on the AngularJs website as they are very clear and easy to follow. Thanks!

  2. Amruth says:

    Thanks Buddy for the great tutorial, it was very helpful for beginner like me.You have pointed the things in a very understandable manner.

  3. trendrumah says:

    it helped me, understandable
    Thanks

  4. JSolo says:

    Wonderful stuff! Was able to connect to SQL server db via express.js to serve up nice rest api and get some nice UI going

    Thanks so much!!!

  5. Anup kumar says:

    I am also trying to call a method of one service into the other service but it is giving error saying
    Cannot read property ‘create’ of undefined

    Java script code here [/code javascript]

    app.service(‘CookieService’, [‘$cookies’,
    function ($cookies) {
    this.create = function (token, userName) {
    $cookies.token = token;
    $cookies.name = userName;
    };
    return this;
    }]);

    app.service(‘AuthService’,
    function (CookieService) {
    return {
    login: function (credentials) {
    CookieService.create(token,username);
    }
    };
    });

    Please ignore syntax error if it is there

  6. Al says:

    We needed an example of using a factory. Please work on your english. Thanks.

  7. Syed Shaik shavali says:

    Thanks..Good article.

  8. Jason Maggard says:

    Thanks a million. Very well explained and easy to follow. Very much appreciated.

  9. Ankit says:

    Well explained article ,thanks a lot for your blog.

  10. rick says:

    Great example Viral, (and your English is just fine). Thank you.

  11. Martin says:

    One of the best tutorials I have used in a long time. Well done. Perhaps a little more info on pros and cons of factory\service approaches.

  12. Haresh says:

    After seeing your tutorial I can started with AngularJS Project. THANKS………..

  13. evans says:

    it was very helpful. thanks

  14. Tuan Nguyen says:

    Thanks so much! I can see how service and factory work and how they connect with controller

  15. Nishant says:

    Thanks for the tutorial..
    the simplified way in which you explained the concepts is commendable

  16. Very good Example and Easy to Under stand for Every one. Thanks Lot

  17. anil says:

    is there any way to create multiple instances of a factory in another factory ?
    //factory 1
    module.factory(‘MyService’, function() {

    });

    //factory2
    module.factory(‘MyService1′, [ ‘MyService’ , function( MyService) {
    var obj = new MyService();
    }]);

  18. anil says:

    is there any way to create multiple instances of a factory in another factory ?
    //factory 1
    module.factory(‘MyService’, function() {
    });
    //factory2
    module.factory(‘MyService1′, [ ‘MyService’ , function( MyService) {
    var obj = new MyService();
    }]);

  19. William says:

    This was an incredibly well-written and informative tutorial. Thanks for sharing your wealth of knowledge. This really clarified things for me. Cheers again!

  20. Sumanth says:

    Thank you so much. This article helped me a lot in understanding AngularJS. This is very easy to follow.

  21. Palak says:

    Awesome article !!

  22. Balachandar says:

    Welldone…Excellent Explanation…Keep the good work…

  23. channu yatnur says:

    Thank you very much….great tutorial

  24. Arun says:

    nice article

  25. Derek says:

    Excellent tutorial. This is very clear and the example using the service approach works nicely! Thanks for posting it. You should help on the next O’Reilly Angular book. They could use it :-)

  26. jdawg says:

    Section one, last sentence, “Thus our application becomes for modular and testable.” I think you meant to write more, not for.

    Thanks,

    Grammar Guy

  27. jdawg says:

    Section one, third paragraph, first sentence. “Thus service is a stateless object that contains some useful functions.” I think you meant to write The, not Thus…

  28. Abu Noman says:

    Nice tutorial, Good job…… Thnx

  29. Thank you. It’s easy to follow.

  30. rohini says:

    Very good tutorial really even for beginners also it’s very easy to understand not only this post for Java, JQuery,spring i am getting good knowledge from this site….Thank you so much viral

  31. Himali says:

    Its great tutorial for beginner!!! Thank you a lot!!!

  32. Adonis says:

    Thanks a lot, this was very informative about controllers and services. Well done.

  33. Chandra Shelar says:

    Very simple way to explain. I cleared my concepts using your articles & examples.
    Can you please add custom directive tutorial?

    Thnx
    Chandra

  34. Great article, much easier to follow than a lot on the web – at last an article that KISS!

  35. A says:

    This was lucid. Thanks for taking time to write this.

  36. Sandy says:

    Thanks Viral, for the excellent tutorial, it’s very easy to understand & to practice the tutorials these were really helpful, waiting to see the new interesting topics on Angular JS.

    Thanks,
    Sandeep.

  37. Modela Satyam says:

    Thanks Viral, excellent tutorial, nice flow, easy to understand.

  38. NaveenKumar says:

    Awesome tutorial with examples, even a biginners can follow these and get into knowledge of subject easily.
    Thanks a lot

  39. Chiranjeevi says:

    Thanks Viral, Please send a post on AngularJS with RESTful web services.

  40. Huy says:

    An excellent tutorial. Thank you so much. By the way, could you please tell me whether it can read a json from an URL instead of directly initialize in the service.js file? (For example, you have written //contacts array to hold list of all contacts
    var contacts = [{
    id: 0,
    ‘name': ‘Viral’,
    ’email': ‘hello@gmail.com’,
    ‘phone': ‘123-2343-44′
    }];
    and I want to read dynamic data from an URL)
    Thanks.

  41. ahmet says:

    Thanks this blogentry.I understood how to be use service , controller together .. thank you again

  42. Meesam Zaidi says:

    Nice job buddie, Thanks a lot.

  43. Ofir Aghai says:

    nice guide,
    But you dont explain much on the main question, when should i use Service, and when we should Factory

  44. Arjun says:

    Nice explanation of service and factory I was struggling a lot now you made me clear. Thank you so much………. :)

  45. Bhavuk says:

    Clearrd many doubts regarding angular.
    Thanks buddy (y)

  46. Amit Kumar Dubey says:

    This is classic, you explained with serenity .
    Thanks Guru!

  47. bs says:

    Good article. One thing not clear to me that when to use service and when to use factory?

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>