If you are searching for this it’s probably because you are trying to figure out which one is the right one for you to use. Or because you’ve come across the three of them and are trying to determine the difference because they seem similar.
If you think they are similar – you’re right. They are very similar. In fact, they are all the the same thing.
They are all providers. The factory and the service are just special cases of the provider, but you can accomplish everything you want using just provider. I’ll show you.
The Provider
We’re going to create a provider that returns a value and simply display that value, you would do this:
<body ng-app="MyModule"> <div ng-controller="MyController"></div> </body>
var mod = angular.module("MyModule", []); mod.provider("myProvider", function() { this.$get = function() { return "My Value"; }; }); mod.controller("MyController", function(myProvider) { console.log("MyController - myProvider: " + myProvider); });
CONSOLE OUTPUT
MyController - myProvider: My Value
A working interactive example can be found at: JS Fiddle.
There, so a “provider” at the core let’s you “provide” a value. That value could be anything. In this case it’s a string with a value of “My Value” but it could easily have been a function or an object.
Note in further code samples I’m going to exclude the <body>
tag and the definition of the mod
for the purpose of keeping the code excerpts short and to the point.
Angular only gets the value once – ever
Note that angular only “gets” the value once, no matter how many times the provider is injected. That means it calls $get()
only once ever, stores the value provided by $get()
, and gives you that same stored value every time.
To show you what I mean I’ll create another controller and inject the provider again with a console statement so that you can see what’s happening.
<div ng-controller="MyController"></div> <div ng-controller="MyController2"></div>
mod.provider("myProvider", function() { this.$get = function() { console.log("MyProviderFunction.$get() called."); // ADDED this line return "My Value"; }; }); mod.controller("MyController", function(myProvider) { console.log("MyController - myProvider: " + myProvider); }); mod.controller("MyController2", function(myProvider) { // ADDED this controller console.log("MyController2 - myProvider: " + myProvider); });
CONSOLE OUTPUT
MyProviderFunction.$get() called.
MyController - myProvider: My Value
MyController2 - myProvider: My Value
As you can see the $get()
function was only called once.
Note that we wrote a bunch of code for the provider only for the purpose of creating a method called $get()
. Why not instead of giving angular a function that defines another function, why not just give it the function we want to run directly instead? Well you can, that’s what Angular calls a factory
.
A Factory
With a factory
you just provide the function body for the $get
method and Angular does the rest. Below is what the new code looks like, as you will see it behaves exactly the same.
mod.factory("myProvider", function() { // CHANGED “provider" to “factory" console.log("Factory function called."); return "My Value"; }); mod.controller("MyController", function(myProvider) { console.log("MyController - myProvider: " + myProvider); }); mod.controller("MyController2", function(myProvider) { console.log("MyController2 - myProvider: " + myProvider); });
CONSOLE OUTPUT
Factory function called.
MyController - myProvider: My Value
MyController2 - myProvider: My Value
Now you might be wondering why would you ever use a provider
if you can accomplish the same thing with a factory
with less code. There are a couple of reasons and I’ll go into that later, right now I want to stay true to the title of this post and address the difference between these two (provider and factory) and a service.
So far we’ve returned a simple string value, but in practice what we probably want to return most of the time is an object. Well that wouldn’t change our example very much we can very easily swap out the string we’re returning with an object instead.
For example let’s do that by returning an object that contains a function called getValue()
. Now there are several ways you can create an object in JavaScript, we’re going to use the “Object Constructor” approach where we create a function that populates an object with properties and functions and uses the new
keyword to instantiate it.
function MyObject() { // ADDED our object constructor this.getValue = function() { return "My Value"; }; } mod.factory("myProvider", function() { console.log("Factory function called."); return new MyObject(); // CREATE an instance of our object }); mod.controller("MyController", function(myProvider) { console.log("MyController - myProvider: " + myProvider.getValue()); // CHANGED to call getValue() }); mod.controller("MyController2", function(myProvider) { console.log("MyController2 - myProvider: " + myProvider.getValue()); // CHANGED to call getValue() });
CONSOLE OUTPUT
Factory function called.
MyController - myProvider: My Value
MyController2 - myProvider: My Value
Now I want to make one small tweak to this because it will lead nicely into the next concept. In our example we create the “Object Constructor” function MyObject()
, but since we’re only instantiating it in one place we can use an anonymous function instead.
This is a very small tweak. Instead of this:
function MyObject() { this.getValue = function() { return "My Value"; }; } mod.factory("myProvider", function() { console.log("Factory function called."); return new MyObject(); });
We do this:
mod.factory("myProvider", function() { console.log("Factory function called."); return new function() { // INLINED our object constructor this.getValue = function() { return "My Value"; }; }; });
So the whole thing now looks like this:
mod.factory("myProvider", function() { console.log("Factory function called."); return new function() { // INLINED our object constructor this.getValue = function() { return "My Value"; }; }; }); mod.controller("MyController", function(myProvider) { console.log("MyController - myProvider: " + myProvider.getValue()); }); mod.controller("MyController2", function(myProvider) { console.log("MyController2 - myProvider: " + myProvider.getValue()); });
Now since our whole factory
is made up of a single object, wouldn’t it be nice if we could just give Angular the object constructor function instead of having to write that funky looking factory
. Well you are in luck, this is exactly what a service
is.
At your Service
Here is that same code except using a service
instead of a factory
.
mod.service("myProvider", function() { // CHANGED "factory" to "service" // NOTE that the only function being passed is the object constructor from before this.getValue = function() { return "My Value"; }; }); mod.controller("MyController", function(myProvider) { console.log("MyController - myProvider: " + myProvider.getValue()); }); mod.controller("MyController2", function(myProvider) { console.log("MyController2 - myProvider: " + myProvider.getValue()); });
CONSOLE OUTPUT
MyController - myProvider: My Value
MyController2 - myProvider: My Value
Provider vs Factory vs Service
So in summary, provider
, factory
, and service
are all providers. A factory
is a special case of a provider
when all you need in your provider is a $get()
function. It allows you to write it with less code. A service
is a special case of a factory
when you want to return an instance of a new object, with the same benefit of writing less code.
When to use one versus the other?
The answer is you use the most specialize version that accomplishes your goal. Say for example you are returning an existing object defined somewhere else that takes constructor arguments. You can’t pass arguments to the service, so you would make the call with a factory instead.
mod.factory("myProvider", function() { console.log("Factory function called."); return new SomeMessageBoxClass("custom argument"); });
One of the main factors of deciding between a provider
and factory
is whether you want to be able to configure the object that is generated before it’s generated. You do this by calling module.config()
and getting an instance to the provider itself (instead of the object returned by the provider). You do this by appending “Provider” to the end of your provider’s name when you are injecting it.
Here is an example of how you would do that:
mod.provider("myProvider", function() { this.value = "My Value"; this.setValue = function(newValue) { this.value = newValue; }; this.$get = function() { return this.value; }; }); mod.controller("MyController", function(myProvider) { console.log("MyController - myProvider: " + myProvider); }); mod.config(function(myProviderProvider) { // ADDED config section // Note the extra "Provider" suffix myProviderProvider.setValue("New Value"); });
That covers when to use the three providers: provider
, factory
, and service
. There is one additional provider that was not mentioned here that is yet another special case and that’s the value
provider.
If you remember when we first introduced the factory
provider above we gave the simple example of returning a string value. That looked like this:
mod.factory("myProvider", function() { return "My Value"; });
Well we could have actually done that using the value
provider instead, again the benefit being that you can do it in less code. The code below does the same thing as the code above:
mod.value("myProvider", "My Value");
So when would you use one versus the other? Presumably you would use the factory
provider when you want to calculate the value based on some other data, for example data from another value provider or an external source. And/or when you want to calculate the value if and only when it’s first requested. Here are some examples:
// Example where factory depends on a "value" provider mod.value("multiple", 3); mod.factory("value", function(multiple) { return 10 * multiple; });
// Example where factory depends on external data mod.factory("value", function(multiple) { var multiple = getDateFromExternalPage(); return 10 * multiple; });
Did I imply that value
was the only other provider? Well I lied, there is another that is very similar to value
with two minor differences. That provider is called constant
.
The difference between value
and constant
is that a value specified using constant
is available during the configuration phase. You might remember from earlier that I mentioned that provider
was accessible from the configuration phase, but service
and factory
were not.
Well it’s the same for value
and constant
. constant
is available from the configuration phase and value
is not. The other difference is as the name implies you can’t change the value of a constant. The first value you assign it is the value it keeps, if you try to assign it a different value later it will be ignored.
Here’s an example:
mod.value("myValue", "First Assignment"); mod.value("myValue", "Second Assignment"); mod.constant("myConstant", "First Assignment"); mod.constant("myConstant", "Second Assignment"); mod.controller("MyController", function(myValue, myConstant) { console.log("myValue: " + myValue); console.log("myConstant: " + myConstant); });
CONSOLE OUTPUT
myValue: Second Assignment
myConstant: First Assignment
Here is a summary of when to use each:
value | You are providing a simple literal value. |
mod.value("myValue", 10); |
constant | You need to be able access that value during the configuration phase. (using .config() ) |
mod.constant("myValue", 10); mod.config(function(myValue) { console.log(myValue); }); |
factory | The value you are providing needs to be calculated based on other data. |
mod.factory("myFactory", function() { return 10; }); |
service | You are returning an object with methods. |
mod.service("myService", function() { var name = "Bob"; this.setName = function(newName) { this.name = newName; }; this.getName = function() { return this.name; } }); |
provider | You want to be able to configure, during the config phase, the object that is going to be created before it’s created. |
mod.provider("greeter", function() { var name; this.setName = function(newName) { name = newName; }; this.$get = function() { return new function() { this.sayHi = function() { console.log("Hi " + name; }; }; }; }); mod.config(function(greeterProvider) { greeterProvider.setName(“John"); }); |
To drive the point home one last time here is a image of a provider with the factory, value, and service portions highlighted:
If you found this useful and want to take it with you you can download a formatted PDF cheat sheet by filling out the popup on this page or clicking here: Get the AngularJS provider cheat sheet.
Newbie says
There is maybe an error in the factory summary table.
p.s. I don’t have fb
Luis Perez says
Thanks for that gani. I went ahead and made the fix.
easoncxz says
The summary code snippets for “constant” and “factory” are the same. Perhaps it was a mistake?
Luis Perez says
Thanks for catching that easoncxz. I updated the post with the fix.
Anand Dev Singh says
Hi Luis ,
It is simply great. Thanks for sharing this article.
I would like to encourage you, always keep doing good work.
Brian Kim says
Hi. The last section where you are using color to highlight. The place where you are demonstrating service just before mod.value(….) . You have used mod.factory(…). Isn’t that supposed to be mod.service(…);
Luis Perez says
Great catch Brian, thanks for pointing that out. I went ahead and corrected the image.
Matías says
Nice explanation! I was a little bit confused, I didn’t know the differences. Thank you.
sunil khankriyal says
very good article ,explanation is very good keep it up..
Vijay says
This is simply superb. This is what i exactly looking for :)
Jose Apollo says
nice!!!
Asanka says
explained Simply. Good job.
Nivash says
Nice article
Roshithlal says
Very nice tutorial, Thanks for sharing this knowledge in a simple way.
Madhuri says
Excellent Job!!!
Basavaraj H says
Great article Luis! I appreciate it. Thanks
sNju says
very helpful for me!…thanks!!
Prabhjot Kaur says
Hi Luis,
Thanks a lot for sharing this piece of information. I could easily understand the differences between all of them and when to use them. It helped me a lot.
Keep it up !
Rajesh says
Nice explanation! Thank you very much!
Said says
Thank yo so so much, I had been trying to understand from thousands of resources on the web, read many posts but this is exactly what I seek.
Akbar S A J says
Thank you – Explained in the simplest way. Very helpful.
Sreyas MN says
It’s really nice article to understand the deference between Provider, Service, Factory, Value and Constant. Great work..
Girish says
thank you
Rahul Sahu says
You said that “You can’t pass arguments to the service” but we can;
See below code –
module.value(“multiple”,4);
module.service(‘myFactory’,function(multiple){
this.getValue = function(value){console.log(“calling getValue from service…”);
return value*multiple;
};
});
Please let me know if I am going down a wrong path
Rahul Sahu says
Got clear most of the confusion only one remains. :)
Luis Perez says
The code you wrote absolutely works. My example was if you didn’t want to use injection, if you wanted to pass a value that didn’t need to be configurable. Useful if you didn’t want to pollute your angular “provider namespace”. Granted not a big concern in most cases. Now this next part my not be directly related to your question but I thought it was worth mentioning since without that big difference between service and provider you might be asking what’s the real difference. Well keep in mind that with service you are essentially providing the definition of a class, so there can only be one class. But with the `factory` or `provider` you could return a completely different class depending on how it was configured or what arguments were injected. Hope that makes sense.
Rahul Sahu says
Thanks a lot, Luis
You explained very well.
shetu says
im a newbie …. but i like to learn everything in deep……….. and with demonstrable proof you made my day.
thankyooooooooou
Bulkesh says
Great Tutorial, in simple way. Great Job. Thankyou very much.
Ronaldo says
Thanks for sharing, it is very important to who is starting with angular.
HaiTao says
This is probably the best article on this topic I have read so far. Thanks for sharing your knowledge!
Izhar says
Great explanation !
Thanks
Maxim says
Thank Luis! Easy to follow article with good examples. I wish Angular documentation be as good.
Vikas says
Thank you for sharing.
Dk says
Awesome article. Such a nice explanation. Thanks for sharing.