Angularjs and Services

Angular services are substitutable objects that are wired together using dependency injection (DI).Angular services are:
Lazily instantiated – Angular only instantiates a service when an application component depends on it.
Singletons – Each component dependent on a service gets a reference to the single instance generated by the service factory.
Angular offers several useful services (like $http).To use an Angular service, add it as a dependency for the component that depends on the service. Angular’s dependency injection subsystem takes care of the rest.It holds some business logic.controller must be responsible for binding model data to views using $scope. It does not contain logic to fetch the data or manipulating it.

service.jpg

For that we must create singleton objects called services. AngularJS can manage these service objects. Wherever we use the service. We just have to specify its name and AngularJS inject these objects.

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

Creating Services :

Application developers are free to define their own services by registering the service’s name and service factory function, with an Angular module.

The service factory function generates the single object or function that represents the service to the rest of the application. The object or function returned by the service is injected into any component that specifies a dependency on the service.

In AngularJS anything that’s either a primitive type, function or object can be a service.Although the concept of service is quite straight forward, the declaration of them in AngularJS isn’t:

There are 4 different ways to declare a service.

  • Registering a existing value as a service
  • Registering a factory function to create the singleton service instance
  • Registering a constructor function to create the singleton service instance
  • Registering a service factory which can be configured.

As we can see we can declare services in 4 different ways. So, now let us discuss about this different methods .

Registering an existing value as a service:

To create a singleton service by registering an existing value,we can use the methods mentioned below.

  • “constant(name, value)”: Intended for registering configuration data and should therefore only be used with primitives or object containing just data.
  • “value(name, value)”: Registers a primitive, existing object instance or function.services registered with “value” as well as the 3 other ways can even be proxied.

Let us see a basic format with this method :


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

function UsingConstantServiceCtrl(value) {
  $scope.value = value;
  }

(function() {
  var existingServiceInstance = {
    getvalue: function() {
      return value; 
    }
  };

  app.value('valueService', existingServiceInstance);
}());

function UsingValueServiceCtrl(valueService) {
  $scope.valueFromService = valueService.getvalue();
}

Registering a factory function to create the singleton service instance:

Instead of supplying an existing value, we can also register a factory function for the service.Because of the “singletons” the factory function is invoked once.A factory function can optionally take parameters which, just like controllers and directives, which will be injected by AngularJS.

Using the earlier model. We can use the registered value ‘service’. We can now declare a service using the “factory(name, providerFunction)”:

(function() {
  // registers a service factory with "value" injected
  app.factory('valueService', function(value) {
    return {
      getvalue: function() {
        return value;
      }
    };
  });
}());

Registering a constructor function to create the singleton service instance:

Instead of registering a factory function that returns an instance of a service.We also can register a constructor function for your service object using the “service(name, constructor)” method.

Registering a service factory which can be configured:

There is way more advanced way to register a service factory using “provider(name, providerType)” which can be configured used the “Module#config(configFn)”. Using the “provider(name, providerType)” We can register “providerType”.This “providerType” can be either an existing object or a constructor function containing.Any number of configuration methods a “$get” factory function just like the one used with “factory(name, providerFunction)” Using “provider(name, providerType)”.

So, now we have 4 different kind of techniques ,which we can use to create services. Having this much options really makes easier to complete the project. But, we do not know when to use which method. Because using a non-compatible type of method will only make things more complex. So, before using we should consider to know when we should use which process.

To ease choosing between the 4 different ways let’s shortly recap all of them:

  • Use either “value(name, value)” or “constant(name, value)” to register an existing value:
  • We can use “value” to register a service object or a function
  • whereas “constant” should only be used for configuration data
  • “factory(name, providerFunction)”: registers a factory function responsible for creating the “singleton” service instance.
  • Just like “value(name, value)” a factory function could return anything from primitive type, function or object instance.
  • “service(name, constructor)”: registers the constructor function which will be constructed using a “new” keyword.
  • “provider(name, providerType)”: the most advanced way to register a service.

AngularJS internal services:

AngularJS internally provides many services that we can use in our application. $http is one example . All angular 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. As for example:

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

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.

var module = angular.module('myapp', []);
 module.service('chapterService', function(){
    this.users = ['angular service', 'angular routing'];
});

Injecting dependencies in services:

Angularjs provides out of the box support for dependency management.
As per Wikipedia “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.”.

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. We can define a service which does certain tasks and inject it . In that way we can be sure of the tested service code works without any glitch.
Like it is possible to inject service object into other angular constructs. We 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.

MathService – A simple custom angular service that has 4 methods: add, subtract, multiply and divide.
CalculatorService – This service has dependency on MathService and it uses MathService.multiply method to do its work.
CalculatorController – This is a simple controller that handler user interactions.

HTML code:

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

Js file:

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);
  };
});
app.controller('CalculatorController', function($scope, CalculatorService) {
  $scope.doSquare = function() {
    $scope.answer = CalculatorService.square($scope.number);
  }
});

calculator

Related Links:
1>Directive in Angular.js – Part 1
2>Directive in Angular.js – Part 2
3>Working with Modules in Angular.js
4>Angular Router and UI-Router
5>Angular.js Promise
6>Angular.js Two Way Data Binding
7>How To Use Filter In Angular.js
8>Angular Templates
9>Using Controllers in Angular.Js
10>Angularjs with Server Side Interaction
11>Working Through Angular.js With Transclude
12>Angular.js Event Handling

If you find this article helpful, you can connect us in Google+ and Twitter.