Understanding Services in AngularJS

Services in AngularJS provide a method for us to keep data around for the lifetime of the app and communicate across controllers in a consistent manner. Services are singleton objects that are instantiated only once per app (by the $injector) and lazyloaded (created only when necessary). They provide an interface to keep together those methods that relate to a specific function.

Services in AngularJS are JavaScript functions that are responsible to perform a specific task. The purpose of AngularJS service / factory function is to generate a single object or function that represents the service to rest of the application. Services are normally injected into controllers, filters, etc. using the dependency injection mechanism of AngularJS.

AngularJS provides many in-built services like $http, $route, $window, $location etc. Each service is responsible for a specific task. For example, $http is used to make ajax calls while $route is used to create routes. Inbuilt services in AngularJS are always prefixed with the $ symbol.

It is recommended to put our business logic into services. It helps in separation of concerns. Since AngularJS provides robust support for unit testing, we can quickly write tests for our services, making them less error prone.

Options for creating a service:

  1. Factory()
  2. Service()
  3. Constant()
  4. Value()
  5. Provider()

Factory()

The factory() method is a quick way to create and configure a service. They are useful for returning a ‘class’ function that can then be new’ed to create instances.

Syntaxmodule.factory('serviceName', function);

Service()

If we want to register an instance of a service using a constructor function, we can use service(), which enables us to register a constructor function for our service object.

Syntaxmodule.service('serviceName', function);

 Provider()

Provider methods are factories that are created through the $provider service and is responsible for instantiating them at run time. A provider is an object with a $get() method. The $injector calls the $get method to create a new instance of the service. The $provider exposes several different API methods for creating a service, each with a different intended use.

Syntaxmodule.provider('providerName', function);

When we look at the definition of a Provider, one question that arises is why would we ever need to use the .provider() method when we can just use the .factory() method? Well, the answer lies in whether we need the ability to externally configure a service returned by the .provider() method using the Angular .config() function.

If we want to be able to configure the service in the config() function, we must use provider() to define our service.

Constant()

It’s possible to register an existing value as a service that we can later inject into other parts of our app as a service. For example, let’s say we want to set an api key for a back-end service. We can store that constant value using constant().

Syntaxmodule.constant('constantName', value);

Value()

If the return value of the $get method in our service is a constant, we don’t need to define a full service with a complex method. We can simply use the value() function to register the service.

Syntaxmodule.value('constantName', value);

When to use a Service() and a Factory()?

Services could be useful for sharing utility functions that are useful to invoke by simply appending () to the injected function reference.

Factories could be useful for returning a class function that can then be new’ed to create instances.

When to use a Value() and a Constant()?

The major difference between the value() method and the constant() method is that you can inject a constant into a config function, whereas you cannot inject a value. Conversely, with constants, we’re unable to register service objects or functions as the value. Typically, a good rule of thumb is that we should use value() to register a service object or function, while we should use constant() for configuration data.

Top