10AviationBPABusiness licensingCMSCMS_1Computer and mobile accessoriesComputer SoftwareCRMCybersecurityDesktopDigital marketingDiversityEmbeddedEntertainmentFarmingGamblingHelthcareHomeInsuranceIoTIoT_1LawMachine LearningMediaMilitaryMobileMobile_1QAQA_1Real EstateRestaurantsSocial projectSocialSocial projectSocial project_1Software developmentSportTransport

Understand AngularJS services

by Artem Deikun

September 21, 2016
scroll

AngularJS have 5 few ways to create service in AngularJS:
provider(); factory(); service(); value(); constant()
If you don’t know the difference then it’s better to reed official documentation or go through my notes. The point is to choose method consciously.

Before new service can be created AngularJS should know about this service. Service previously registered by $provide function.

Provider

So, the most fundamental method of create the service is:

$provide.provider().

app.config(function($provide){
     $provide.provider('testService', function() {
        this.$get = function(){
            var title = 'Project';
            return {
                title: title
            };
        }
    });
});

Working snippet on CodePen.

The benefit of this function is ability of configure this service in module.
app.config() with injected $provide function.

Also we can create provider directly from the module object and example of configuration some parameters.

app.provider('testService', function(){  
     this.titleId  = 1;
     this.$get = function(){
          var title = 'Project #' + this.titleId;          
          return {
               title: title
          };       
     }     
});
app.config(function(testServiceProvider){
     testServiceProvider.titleId = 2;
});

Working snippet on CodePen.

Instead of injecting the provide service in config - inject the testServiceProvider. (“Provider” automatically appends the name of the service).

Factory and Service

Investigating AngularJS core we can find factory() and service () function.
And it looks like just wrappers around provider() function.

https://github.com/angular/angular.js/blob/v1.5.x/src/auto/injector.js

Let’s compare factory() example:

app.factory('testService', function(){  
  return {
    testList: function(){
      return ['item1', 'item2', 'item3']
    }
  }
});
app.controller('TestController', function(testService, $scope) {
    $scope.testList = testService.testList();
});

with service() example:

app.service('testService', testService);
function testService() {
  TestServiceBase.call(this);    
  this.testList = function(id) {
    return ['item1 ' + this.version(id), 
            'item2 ' + this.version(id), 
            'item3 ' + this.version(id)];
  }  
}
function TestServiceBase() {}
TestServiceBase.prototype.version = function(id){ 
     return "version #" + id;
}
testService.prototype = Object.create(TestServiceBase.prototype);
app.controller('TestController', function(testService, $scope) {
    $scope.testList = testService.testList(2);
});

(working snippet of factory on CodePen)
(working snippet of service on CodePen)

As you see, difference between service and factory is that the function you passed to the service method will be treated as a constructor function and called with the JavaScript “new” operator. So, service() is better for inheritance.

Example of service can be pretty complicated. I will put here the same server of getting testList as simple as possible (CodePen).

app.service('testService', function(){
  this.testList = function() {
    return ['item1 ', 'item2 ', 'item3 '];
  }  
});

Value and Constant

Constant service — simply register service with injector. The only of functions here that is not wrapper of provider() function.

Constant is good for storing static data and can be injected in module configuration function and can’t be overwritten.

app.constant('constants', {
     APP_TITLE: 'Project',
     APP_VERSION: '1'
});
app.config(function(constants){
  console.log(constants.APP_TITLE);
});

Working snippet on CodePen.

Value — is shorthand of factory function. Good for use if you have nothing to inject. Value service can store functions with attributes.

app.value('testService', {
  retrieveVersion: function(version) {
    var status;
    if (version == 3) {status = 'alpha';}
    else if (version == 2) {status = 'stable';} 
    else if (version == 1) {status = 'legacy';}
    else {status = 'unknown';}
    return status;
  }
});

Working snippet on CodePen.

Using services

Using services in controllers or another services looks the same.
We inform injector what services to inject with dependency annotation.

DA as function parameter names (the simplest) 
(you can find example in any CodePen snippet above)

app.controller('TestController', function(testService) {
     console.log(testService);
});

DA as inline array annotation (good for minification)

app.controller('TestController', ['testService', function(testService) {
     console.log(testService);
}]);

With inject method

app.controller('TaskController', function(testService){
     console.log(testService);
}.$inject = ['testService'])

Summary

It’s better to create service with technique that is better match requirement for service functionality and it’s destination.

  • Provider — when we need to configure it dynamically in config function.

  • Factory — as a simple, regular service

  • Service — when we need to inherit something.

  • Value — when we don’t need any injections and have no dependency.

  • Constant — as a storage of values.

Thanks for great tutorial by Brice Wilson — AngularJS Services In-depth
It was the main inspiration for this article.

by Artem Deikun
September 21, 2016

Related articles

angular logo
Localisation AngularJS 1.x applications
by Svitla Team
January 17, 2017
article
article
Using Placeholders and Input Fields
A popular pattern in web design uses the input field, a placeholder that slides up on focus or while a user is typing. Different frameworks that are based on material design implement it in different ways, but each of them uses JavaScript to handle changes in the input field. Can we solve this problem with no JS code?
by Svitla Team
November 14, 2016
article

Stay informed - subscribe!

Join our newsletter and get the latest content right in your inbox once or twice per week.

Now you will get awesome news!