Skip to content

Instantly share code, notes, and snippets.

@demisx
Last active March 17, 2024 11:09
Show Gist options
  • Save demisx/9605099 to your computer and use it in GitHub Desktop.
Save demisx/9605099 to your computer and use it in GitHub Desktop.
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/

@surfbuds
Copy link

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
Copy link

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
Copy link

dotku commented May 4, 2016

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

@thisismanish
Copy link

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

@thisismanish
Copy link

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
Copy link

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
Copy link

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
Copy link

@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
Copy link

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