After reading a lot of articles and sample code it wasn’t clear to me what the difference was between the several providers like provider, factory and service. Without this knowledge you could not select the proper provider. I will explain the differences between the providers with examples.





What is a provider?

If you look at the AngularJS docs you will find the next definition of a provider:

A provider is an object with a $get() method. The injector calls the $get method to create a new instance of a service. The Provider can have additional methods which would allow for configuration of the provider.

AngularJS uses $provide to register new providers. The providers basically create new instances, but only once for each provider. The $provide has six methods to create custom providers and I will explain each one of them with the help of sample code. These providers are available on $provide:

constant

A constant can be injected everywhere. A constant can not be intercepted by a decorator, that means that the value of a constant can never be changed.

[code language=”javascript”]

var app = angular.module(‘app’, []);

app.config(function ($provide) {

$provide.constant(‘movieTitle’, ‘The Matrix’);

});

app.controller(‘ctrl’, function (movieTitle) {

expect(movieTitle).toEqual(‘The Matrix’);

});

[/code]

AngularJS provides a convenience method for creating a constant. You can rewrite the lines 3-5 to:

[code language=”javascript”]

app.constant(‘movieTitle’, ‘The Matrix’);

[/code]



value

A value is nothing more than a simple injectable value. The value can be a string, number but also a function. Value differs from constant in that value can not be injected into configurations, but it can be intercepted by decorators.

[code language=”javascript”]

var app = angular.module(‘app’, []);

app.config(function ($provide) {

$provide.value(‘movieTitle’, ‘The Matrix’)

});

app.controller(‘ctrl’, function (movieTitle) {

expect(movieTitle).toEqual(‘The Matrix’);

})

[/code]

AngularJS provides a convenience method for creating a value. You can rewrite the lines 3-5 to:

[code language=”javascript”]

app.value(‘movieTitle’, ‘The Matrix’);

[/code]



service

A service is an injectable constructor. If you want you can specify the dependencies that you need in the function. A service is a singleton and will only be created once by AngularJS. Services are a great way for communicating between controllers like sharing data.

[code language=”javascript”]

var app = angular.module(‘app’ ,[]);

app.config(function ($provide) {

$provide.service(‘movie’, function () {

this.title = ‘The Matrix’;

});

});

app.controller(‘ctrl’, function (movie) {

expect(movie.title).toEqual(‘The Matrix’);

});

[/code]

AngularJS provides a convenience method for creating a service. You can rewrite lines 3-7 to:

[code language=”javascript”]

app.service(‘movie’, function () {

this.title = ‘The Matrix’;

});

[/code]



factory

A factory is an injectable function. A factory is a lot like a service in the sense that it is a singleton and dependencies can be specified in the function. The difference between a factory and a service is that a factory injects a plain function so AngularJS will call the function and a service injects a constructor. A constructor creates a new object so new is called on a service and with a factory you can let the function return anything you want. As you will see later on, a factory is a provider with only a $get method.

[code language=”javascript”]

var app = angular.module(‘app’, []);

app.config(function ($provide) {

$provide.factory(‘movie’, function () {

return {

title: ‘The Matrix’;

}

});

});

app.controller(‘ctrl’, function (movie) {

expect(movie.title).toEqual(‘The Matrix’);

});

[/code]

AngularJS also provides a convenience method for lines 3-9. You can rewrite it to:

[code language=”javascript”]

app.factory(‘movie’, function () {

return {

title: ‘The Matrix’;

}

});

[/code]



decorator

A decorator can modify or encapsulate other providers. There is one exception and that a constant cannot be decorated.

[code language=”javascript”]

var app = angular.module(‘app’, []);

app.value(‘movieTitle’, ‘The Matrix’);

app.config(function ($provide) {

$provide.decorator(‘movieTitle’, function ($delegate) {

return $delegate + ‘ – starring Keanu Reeves’;

});

});

app.controller(‘myController’, function (movieTitle) {

expect(movieTitle).toEqual(‘The Matrix – starring Keanu Reeves’);

});

[/code]



provider

A provider is the most sophisticated method of all the providers. It allows you to have a complex creation function and configuration options. A provider is actually a configurable factory. The provider accepts an object or a constructor.

[code language=”javascript”]

var app = angular.module(‘app’, []);

app.provider(‘movie’, function () {

var version;

return {

setVersion: function (value) {

version = value;

},

$get: function () {

return {

title: ‘The Matrix’ + ‘ ‘ + version

}

}

}

});

app.config(function (movieProvider) {

movieProvider.setVersion(‘Reloaded’);

});

app.controller(‘ctrl’, function (movie) {

expect(movie.title).toEqual(‘The Matrix Reloaded’);

});

[/code]



Summary

All the providers are instantiated only once. That means that they are all singletons.

All the providers except constant can be decorated.

A constant is a value that can be injected everywhere. The value of a constant can never be changed.

A value is just a simple injectable value.

A service is an injectable constructor.

A factory is an injectable function.

A decorator can modify or encapsulate other providers except a constant.

A provider is a configurable factory.