Services, providers & factories

Services

  • Recipes for making development easy
  • Api is defined by developer 
  • Objects Instantiated and wired together for the app to work
  • Initialized only once after that reference is used in the app.

Naming

  • Its messed up....
  • General name 'service'
  • Yet a service is named 'service'
  • Angular team has apologized for it.

Value recipe

Simple values for applications

 

Can be injected throughout the application

Value recipe

angular.module('nuclearApp')

nuclearApp.value('radiationLevel', '2.5677788');
nuclearApp.controller('ExplodeCtrl', ['radationLevel', 
    function ExplodeCtrl(radiationLevel) {
  
    console.log('Radiation level', radiationlevel);
    // 2.5677788
}]);

Initialization

Use

Factory recipe

  • Gives us the function's return value ie. You just create an object, add properties to it, then return that same object

  • Singleton

  • Reusable components

  • Can use other dependencies

  • Usually used when the service instance requires complex creation logic

  • Used for non configurable services

  • If you're using an object, you could use the factory provider.

Factory recipe

myApp.factory('NukeBomb', function(){
    var factory = {};

    return factory;

    factory = {
        triggerIgnition: function(){
            return 'Bomb triggered';
        }
    }
});
nuclearApp.controller('ExplodeCtrl', ['NukeBomb', 
    function ExplodeCtrl(NukeBomb) {
  
    NukeBomb.triggerIgnition();

}]);

Initialization

Use

Service recipe

  • Gives us the instance of a function (object)- instantiated with the ‘new’ keyword and you’ll add properties to ‘this’ and the service will return ‘this’

  • Singleton and will only be created once

  • Reusable components

  • Dependencies are injected as constructor arguments

  • Used for simple creation logic

  • If you're using a class you could use the service provider

Service recipe

myApp.service('NukeBomb', function(){
    
    this.triggerIgnition: function(){
        return 'bomb ignited';
    },

    this.drop: function(){
        return 'bomb dropped awaiting explosion';
    }
});
nuclearApp.controller('ExplodeCtrl', ['NukeBomb', 
    function ExplodeCtrl(NukeBomb) {
  
    NukeBomb.triggerIgnition();
    NukeBomb.dropBomb();

}]);

Initialization

Use

Provider recipe

  • Core recipe type and all the other recipe types are just syntactic sugar on top of it.
  • ​Implements a $get method.
  • Use when exposing an API for application-wide configuration.
  • Rethink if you end up using this in your app code.

Provider recipe

myApp.provider('NukeBomb', function(){
    
    this.codeName = "Destroy ISIS";

    this.$get = function(){
        // any init vars here

        return {
            triggerIgnition: function(){
                return 'bomb ignited';
            },
            drop: function(){
                return 'bomb dropped awaiting explosion';
            }
        }
    }

    this.setCodeName = function(codeName){
        this.codeName = codeName;
    }
    
});

Initialization

Provider recipe

// Config time use
nuclearApp.config(function(NukeBombProvider){
    NukeBombProvider.setCodeName = "Killer bomb";
});


// after run phase in controllers
nuclearApp.controller('ExplodeCtrl', ['NukeBomb', 
    function ExplodeCtrl(NukeBomb) {
  
    NukeBomb.triggerIgnition();
    NukeBomb.dropBomb();

}]);

Use

Main confusions

When to use a service or a factory?

Magic time

nuclearApp.service('NukeBomb', function(){
    
    this.triggerIgnition: function(){
        return 'bomb ignited';
    },

    this.drop: function(){
        return 'bomb dropped awaiting explosion';
    }
});

// Looks like a factory
nuclearApp.service('NukeBomb', function(){
    var killerService;
    return killerService;

    killerService = {
        triggerIgnition: function(){
            return 'bomb ignited';
        },
        drop: function(){
            return 'bomb dropped awaiting explosion';
        }
    }
});

Services can act as factories

Text

Services can act as factories and vice versa.

In angularjs you don't need factories at all services can do all magic for you.

Main distinction

Factories

While injecting you have the instance of the function. In other words new FunctionYouPassedToService()

Services

While injecting you have the value that is returned by invoking the function reference passed to module.factory

Main distinction

Factories

DI using “service”, this creates a new GLOBAL instance of the “Service” object and injects it in to the function.

Services

DI using “factory” it does not create an instance. It just passes the method and later the consumer internally has to make calls to the factory for object instances.

Use cases

  • Share data b/w controllers
  • Exposing api eg. library
  • Common code
  • Constants
  • Config time initialization(Providers)

Share data b/w Ctrls

NuclearApp.factory('ConfidentialData', function () {

    var confidentialData = {
        groundZero: '',
        codeName:   ''
    };

    return {
        getGroundZero: function () {
            return confidentialData.groundZero;
        },
        setGroundZero: function (altitude) {
            confidentialData.groundZero = altitude;
        },
        getCodeName: function () {
            return confidentialData.groundZero;
        },
        setCodeName: function (name) {
            confidentialData.codeName = name;
        }
    };
});

Share data b/w Ctrls

NuclearApp.controller('FirstCtrl', function ($scope, ConfidentialData) {
    $scope.codeName = '';

    $scope.$watch('firstName', function (newValue, oldValue) {
        if (newValue !== oldValue) ConfidentialData.codeName(newValue);
    });
});

Using getters/setters in Controllers

Exposing api(Library)

angular.module('ngAuth', [])
        .provider('$auth', function() {
            var config = {
                permissions:    [],
                customInit:     {}
            };
            // adding extra permission if passed by user
            this.permission = function(permissions){
                
                config.permissions.push(permissions);
                return this;
            }
            // implement $get method
            this.$get = ['$q', '$rootScope', '$window', '$http',  function($q, $rootScope, $window, $http){
                $auth = $q.defer();
    
                /* `property` object should have
                 * api_url as an attribute
                 * it will be used to make api call for login
                 */
                $auth.config = function(property){
                    if(property.api_url != undefind) {
                        config['api_url']= property.api_url;
                    }
                    return config;
                };
            }];
        };

Using providers

Common code

MyApp.service(Helper, function(){
    this.currentDate = function(){ 
       return new Date();
    };

    this.currentScore = funtion(){
       $http.get('some_url', {options})
            .$promise
            .then(function(response){
                return response.data;
            })
            .catch(function(error){
                // error occured
            });
    };

});
MyApp.controller(Ctrl1, function(Helper){
   var vm = this;

    vm.today = Helper.currentDate();
    // this helper method can be shared across multiple controllers
});

Config time init

MyApp.provider(Killer, function(){
    this.name = "Default name";

    this.$get = function(){
        var name = this.name;

        return {
            getName = function(){
                return name;
            },
            setName = function(name){
                name = name;
            }
        };
    };
});
MyApp.config('KillerProvider' function(KillerProvider){

   KillerProvider.setName('Assasin 2');
   // Above defined provider is accessible in config phase as KillerProvider
});

Conclusion

  • Services and factories are both general js recipe
  • They can be used as per need
  • Conventionally factory -> object related tasks.
  • Services -> class related tasks.
  • Providers -> Exposing api

Thank you

 

Questions?

Made with Slides.com