Create a gist now

Instantly share code, notes, and snippets.

Embed
AngularJS Providers: Constant/Value/Service/Factory/Decorator/Provider
Provider Singleton Instantiable Configurable
Constant Yes No No
Value Yes No No
Service Yes No No
Factory Yes Yes No
Decorator Yes No? No
Provider Yes Yes Yes

Constant

A constant can be injected everywhere. A constant can not be intercepted by a decorator, that means that the value of a constant should never be changed (though it is still possible to change it programmatically in Angular 1.x).

angular.module('app', []);
 
app.constant('MOVIE_TITLE', 'The Matrix');
 
.controller('MyController', function (MOVIE_TITLE) {
  expect(MOVIE_TITLE).toEqual('The Matrix');
});

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.

angular.module('app', []);

.value('movieTitle', 'The Matrix');

.controller('MyController', function (movieTitle) {
  expect(movieTitle).toEqual('The Matrix');
})

Service

Use Service when you need just a simple object such as a Hash, for example {foo:1, bar:2} It's easy to code, but you cannot instantiate it. 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.

angular.module('app' ,[]);
 
.service('movie', function () {
  this.title = 'The Matrix';
});
 
.controller('MyController', function (movie) {
  expect(movie.title).toEqual('The Matrix');
});

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.

angular.module('app', []);
 
.factory('movie', function () {
  return {
    title: 'The Matrix';
  }
});
 
.controller('MyController', function (movie) {
  expect(movie.title).toEqual('The Matrix');
});
.factory('catalogueService', function($rootScope, $http) {
  // We first define a private API for our service.

  // Private vars.
  var items = [];

  // Private methods.
  function add( id ) {
    $http.put( $rootScope.apiURL, {id:id} )
    .success(function(data,status,headers,config) { items.push(data); })
    .then(function(response) { console.log(response.data); });
  }

  function store( obj ) {
    // do stuff
  }

  function remove( obj ) {
    // do stuff
  }

  // We now return a public API for our service.
  return {
    add: add,
    store: store,
    rm: remove
  };
};

Decorator

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

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');
});

#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.

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('MyController', function (movie) {
  expect(movie.title).toEqual('The Matrix Reloaded');
});

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.

Extracted from http://blog.xebia.com/2013/09/01/differences-between-providers-in-angularjs/

@edgar0011

This comment has been minimized.

Show comment
Hide comment
@edgar0011

edgar0011 Aug 13, 2014

Hi,

I think you can instantiate VALUE and CONSTANT if those are functions,

module.constant("STATIC_LOGGER", function(){this.name = "logger"});
then somewhere:
var logger = new STATIC_LOGGER();
and same for .value.

Kind regards,

Edgar

Hi,

I think you can instantiate VALUE and CONSTANT if those are functions,

module.constant("STATIC_LOGGER", function(){this.name = "logger"});
then somewhere:
var logger = new STATIC_LOGGER();
and same for .value.

Kind regards,

Edgar

@demisx

This comment has been minimized.

Show comment
Hide comment
@demisx

demisx Sep 16, 2014

Sure Edgar. Plain JavaScript kicks in here. I would, though, keep static logger in a factory service instead of a constant that returns a functions. I prefer to use constants for application-wide settings that I know won't change and that can also be injected in the module config phase. I follow these principles of code organization in Angular: http://demisx.github.io/angularjs/2014/09/14/angular-what-goes-where.html

Owner

demisx commented Sep 16, 2014

Sure Edgar. Plain JavaScript kicks in here. I would, though, keep static logger in a factory service instead of a constant that returns a functions. I prefer to use constants for application-wide settings that I know won't change and that can also be injected in the module config phase. I follow these principles of code organization in Angular: http://demisx.github.io/angularjs/2014/09/14/angular-what-goes-where.html

@shahzadns

This comment has been minimized.

Show comment
Hide comment
@shahzadns

shahzadns Jan 8, 2015

Hey Dmitri ! Awesome post ! But "The value of a constant can never be changed." ?

angular.module( 'app',  [] )

 .constant( 'movie', {
  title: 'something'
 })

 .controller( 'firstCtrl', function ( $scope, movie ){
  $scope.setMovie = function ( newTitle ){
   movie.title = newTitle;
  };
 })

.controller( 'secondCtrl', function ( $scope, movie ){
  $scope.getMovie = function (){
   console.log( movie.title );
 };
 });

If you call setData() from firstCtrl View, and then call the getData from secondCtrl view, you would get the new value against constant 'movie'.

Hey Dmitri ! Awesome post ! But "The value of a constant can never be changed." ?

angular.module( 'app',  [] )

 .constant( 'movie', {
  title: 'something'
 })

 .controller( 'firstCtrl', function ( $scope, movie ){
  $scope.setMovie = function ( newTitle ){
   movie.title = newTitle;
  };
 })

.controller( 'secondCtrl', function ( $scope, movie ){
  $scope.getMovie = function (){
   console.log( movie.title );
 };
 });

If you call setData() from firstCtrl View, and then call the getData from secondCtrl view, you would get the new value against constant 'movie'.

@mikael-georges

This comment has been minimized.

Show comment
Hide comment
@mikael-georges

mikael-georges Jan 21, 2015

@shazadsoomro The goal of using constants is to never change their value and keep them as it is, a bit like having:

var APP_VERSION="1.0"

Regardless you found a way to alter their value, AFAIK constant have always been editable, we just don't change them once declared :)

If you wish to be able to change them use .value rather than .constant

@shazadsoomro The goal of using constants is to never change their value and keep them as it is, a bit like having:

var APP_VERSION="1.0"

Regardless you found a way to alter their value, AFAIK constant have always been editable, we just don't change them once declared :)

If you wish to be able to change them use .value rather than .constant

@boyfunky

This comment has been minimized.

Show comment
Hide comment
@boyfunky

boyfunky Feb 20, 2015

I am currently facing a problem and since new to Angular. I need some more clarification on this. Does this mean that even if you changed your data in your service, the data still wont change because it has already been created? Because i created a factory service and i have removed all data from the function but it still returns the initial data in my controller. So does that means only the controller can be used then? What if i have a webservice that takes parameters to fetch data from an external source does it mean that even when the parameters change the results wouldnt change because it has already been created?

I am currently facing a problem and since new to Angular. I need some more clarification on this. Does this mean that even if you changed your data in your service, the data still wont change because it has already been created? Because i created a factory service and i have removed all data from the function but it still returns the initial data in my controller. So does that means only the controller can be used then? What if i have a webservice that takes parameters to fetch data from an external source does it mean that even when the parameters change the results wouldnt change because it has already been created?

@mcblum

This comment has been minimized.

Show comment
Hide comment
@mcblum

mcblum Mar 28, 2015

Thank you. Thank you 1000.

mcblum commented Mar 28, 2015

Thank you. Thank you 1000.

@raghunandy

This comment has been minimized.

Show comment
Hide comment
@raghunandy

raghunandy May 23, 2015

Thank you ..

Thank you ..

@chaddjohnson

This comment has been minimized.

Show comment
Hide comment
@chaddjohnson

chaddjohnson Aug 6, 2015

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.

I think this is a confusing statement. When injecting a factory (.factory()), whatever the factory returns is injected (which could be a plain object or a plain function), but when injecting a service (.service()), an already-instantiated object is injected. Saying that a constructor is injected when injecting a service makes it seem like a constructor function itself is injected, and this is not the case.

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.

I think this is a confusing statement. When injecting a factory (.factory()), whatever the factory returns is injected (which could be a plain object or a plain function), but when injecting a service (.service()), an already-instantiated object is injected. Saying that a constructor is injected when injecting a service makes it seem like a constructor function itself is injected, and this is not the case.

@stackia

This comment has been minimized.

Show comment
Hide comment
@stackia

stackia Aug 30, 2015

Thank you. Very helpful!

stackia commented Aug 30, 2015

Thank you. Very helpful!

@surfbuds

This comment has been minimized.

Show comment
Hide comment
@surfbuds

surfbuds Nov 22, 2015

Agree with @chaddjohnson, it is confusing to say:

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.

Agree with @chaddjohnson, it is confusing to say:

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.

@houssemzaier

This comment has been minimized.

Show comment
Hide comment
@houssemzaier

houssemzaier Dec 2, 2015

Constants and providers are configurable, you can inject them into the config component.
Provider is the basic component that we can use to be a "service", then we can inject it into any controller.
The factory is a layer on top of the provider , we use it if we don't need to config a provider, it has a cleaner code to read.
The service is a layer on top of the factory we can use it when we need to use the "new" keyword provided by the Angular (you don't want to use that in many cases except OO inheritance ..).
We have 5 types of services in Angular:
1/Provider
2/Factory (it is a provider autoConfugurabe by Angular, if you create a factory called
" myFactory" Angular creates myFactoryProvider for you for free.)
3/Value (it is a factory that u can not inject into it, use it if you don't need to use built in services like $http, $scope... or any other service that you have created )
4/Service (it is a factory , that can use OO inheritance, imagine the scenario that you have a ParentService and some Services children that use some of the parents methods.. Do you really need that ?)
5/Constant (the most evident, it is not a provider but can be configurable, and injected like all those sevices into a controller ).
All of this services are singletons.

Constants and providers are configurable, you can inject them into the config component.
Provider is the basic component that we can use to be a "service", then we can inject it into any controller.
The factory is a layer on top of the provider , we use it if we don't need to config a provider, it has a cleaner code to read.
The service is a layer on top of the factory we can use it when we need to use the "new" keyword provided by the Angular (you don't want to use that in many cases except OO inheritance ..).
We have 5 types of services in Angular:
1/Provider
2/Factory (it is a provider autoConfugurabe by Angular, if you create a factory called
" myFactory" Angular creates myFactoryProvider for you for free.)
3/Value (it is a factory that u can not inject into it, use it if you don't need to use built in services like $http, $scope... or any other service that you have created )
4/Service (it is a factory , that can use OO inheritance, imagine the scenario that you have a ParentService and some Services children that use some of the parents methods.. Do you really need that ?)
5/Constant (the most evident, it is not a provider but can be configurable, and injected like all those sevices into a controller ).
All of this services are singletons.

@dotku

This comment has been minimized.

Show comment
Hide comment
@dotku

dotku May 4, 2016

'Value' actually can be configurated in app.config()

dotku commented May 4, 2016

'Value' actually can be configurated in app.config()

@thisismanish

This comment has been minimized.

Show comment
Hide comment
@thisismanish

thisismanish May 10, 2016

@dotku: We cannot inject 'Value' in config() block. So how we can configure 'Value'.????. If possible give me an example for this.

@dotku: We cannot inject 'Value' in config() block. So how we can configure 'Value'.????. If possible give me an example for this.

@thisismanish

This comment has been minimized.

Show comment
Hide comment
@thisismanish

thisismanish May 10, 2016

Can anybody clear out it that. I can modify 'constant' in controller as well 'value' in controller(I did it in live) either they are object or primitive. then what is exact diff. b/w them(except constant can inject in config block and value can't).

Can anybody clear out it that. I can modify 'constant' in controller as well 'value' in controller(I did it in live) either they are object or primitive. then what is exact diff. b/w them(except constant can inject in config block and value can't).

@davidshepherd7

This comment has been minimized.

Show comment
Hide comment
@davidshepherd7

davidshepherd7 Aug 11, 2016

Nitpick: I think quite a few of your semicolons are wrong, e.g. where you have angular.module('app', []); followed by .value('movieTitle', 'The Matrix');

Nitpick: I think quite a few of your semicolons are wrong, e.g. where you have angular.module('app', []); followed by .value('movieTitle', 'The Matrix');

@calumjames

This comment has been minimized.

Show comment
Hide comment
@calumjames

calumjames Nov 4, 2016

A constant can be injected everywhere
That's not true. A constant can't be injected into another constant. I know you can't inject anything into a constant, but it might be worth pointing that out.

A constant can be injected everywhere
That's not true. A constant can't be injected into another constant. I know you can't inject anything into a constant, but it might be worth pointing that out.

@NishantDesai1306

This comment has been minimized.

Show comment
Hide comment
@NishantDesai1306

NishantDesai1306 Jan 18, 2017

@thisismanish, As mentioned by mikael-georges in commnets above, One can update both constant and value but the reason we have constant service is because it is a convention that value of constant services should not be changed.

Its just a convention just like in JSP _jspService() starts with an _ because it tells that a developer that he/she should not override it.
Hope This helps.

@thisismanish, As mentioned by mikael-georges in commnets above, One can update both constant and value but the reason we have constant service is because it is a convention that value of constant services should not be changed.

Its just a convention just like in JSP _jspService() starts with an _ because it tells that a developer that he/she should not override it.
Hope This helps.

@runesam

This comment has been minimized.

Show comment
Hide comment
@runesam

runesam Jan 25, 2017

thanks a lot man 👍

runesam commented Jan 25, 2017

thanks a lot man 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment