Wednesday, November 5, 2014

services and factories in angular explained

Compilation of very-very useful explanations for beginners what are services and factories and what are their key useful details. Credentials go mostly to stackoverflow.com threads.

Keep in mind all providers in AngularJS ( = value, constant, services, factories) are singletons !

If you want your function to be called like a normal function, use factory. If you want your function to be instantiated with the new operator, use service. If you don't know the difference, use factory.

Services

Syntax: module.service( 'serviceName', function );
Result: When declaring serviceName as an injectable argument you will be provided with an instance of the function. In other words new FunctionYouPassedToService().
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.

Service could be useful for sharing utility functions that are useful to invoke by simply appending () to the injected function reference. Could also be run with injectedArg.call(this) or similar.

Example1
module.service('MyService', function() {
    this.method1 = function() {
            //..
        }
    this.method2 = function() {
            //..
        }
});
Example2
angular.module('myApp.services', [])
  .factory('githubService', function() {
    var serviceInstance = {};
    // Our first service
    return serviceInstance;
  });

Factories

Syntax: module.factory( 'factoryName', function );
Result: 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.
Factory could be useful for returning a ‘class’ function that can then be new’ed to create instances.

Example3
module.factory('MyService', function() {

    var factory = {}; 

    factory.method1 = function() {
            //..
        }
    factory.method2 = function() {
            //..
        }
    return factory;
});

Providers

Syntax: module.provider( 'providerName', function );
Result: When declaring providerName as an injectable argument you will be provided with ProviderFunction().$get(). The constructor function is instantiated before the $get method is called - ProviderFunction is the function reference passed to module.provider.

--

The way to define common code in angular is through Services.
You would define a new service like so :
Example4
.factory('CommonCode', function ($window) {
        var root = {};
        root.show = function(msg){
            $window.alert(msg);
        };
        return root;
    });
In your controller you would inject this service..like so
function MainAppCtrl($scope,CommonCode)
{
     $scope.alerter = CommonCode;
     $scope.alerter.show("Hello World");
}
Just include CommonCode as an argument to your controller function.. Angular will take care of injecting it for you ( Read on Dependancy Injection ..to understand what is happening here. )

--

Samples of built-in AngularJS  services:
  • $http
  • $timeout
  • $log
  • $window
  • $document
  • $rootScope

More links