public
Last active

Difference between Service, Factory and Provider in AngularJS

  • Download Gist
gistfile1.js
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
// Source: https://groups.google.com/forum/#!topic/angular/hVrkvaHGOfc
// jsFiddle: http://jsfiddle.net/pkozlowski_opensource/PxdSP/14/
// author: Pawel Kozlowski
 
var myApp = angular.module('myApp', []);
 
//service style, probably the simplest one
myApp.service('helloWorldFromService', function() {
this.sayHello = function() {
return "Hello, World!"
};
});
 
//factory style, more involved but more sophisticated
myApp.factory('helloWorldFromFactory', function() {
return {
sayHello: function() {
return "Hello, World!"
}
};
});
//provider style, full blown, configurable version
myApp.provider('helloWorld', function() {
// In the provider function, you cannot inject any
// service or factory. This can only be done at the
// "$get" method.
 
this.name = 'Default';
 
this.$get = function() {
var name = this.name;
return {
sayHello: function() {
return "Hello, " + name + "!"
}
}
};
 
this.setName = function(name) {
this.name = name;
};
});
 
//hey, we can configure a provider!
myApp.config(function(helloWorldProvider){
helloWorldProvider.setName('World');
});
 
function MyCtrl($scope, helloWorld, helloWorldFromFactory, helloWorldFromService) {
$scope.hellos = [
helloWorld.sayHello(),
helloWorldFromFactory.sayHello(),
helloWorldFromService.sayHello()];
}‚Äč

I think it's clearer to write the $get function like this:

this.$get = function() {
    var self = this;
    return {
        sayHello: function() {
            return "Hello, " + self.name + "!"
        }
    }
};

But it's a minor point. Fantastic example otherwise. Thank you!

I would love to see this example with service / factory / provider that wraps a resource.

@Mithrandir0x Thanks for your very useful Gist!

It was very useful while writing my blog about: "How to create (singleton) AngularJS services in 4 different ways"

Thank you @Mithrandir0x it was very useful for me too.

The "provider" example is better implemented with the revealing module pattern. In the form above, "name" is public: there really is no reason to have setName. To make "name" private as intended, rewrite it as:

myApp.provider('helloWorld', function() {

    var name = 'Default';

    return {
        $get: function() {
            return {
                sayHello: function() {
                    return "Hello, " + name + "!"
                }
            }
        },
        setName: function(newName) {
            name = newName;
        }
    };

});

Also this is a good egghead.io video on the subject

Its nice to see how they work differently, but why do I need each of them? What do I use them for? Any real life examples on suggested use cases? Maybe a real app with rest and multiple controllers on single page?
Can anyone point me in the right direction? I'm struggling with a simple app wired with a resource and I have no clue how to organize things and make my productListCtrl talk to cartCtrl :/

A believe a service is a singleton and a provider creates a new instance. So if you need to persist some info then a service might be the better way. Someone please correct me if I am wrong. A real world example would be to use a service to retrieve data from a server where you don't want to create a new object every time you need you XHR service object. To be honest i have not used providers at all. So I cannot really speak to their use cases.

I too would like to know a real use case for a provider.

@jonahx True. Relying on variable scope for more privacy concerns is good, although I believe, when Pawel wrote this example, he was showing that when creating a new factory using the function given by the provider, the function was called with the keyword this bound to the provider object itself.

Instead of using a closure, you use this to access to methods and properties of the provider, which Factories and Service have no access to.

@pablodenadai

I feel like our solutions are very similar. However, I am using a service which includes various data manipulation methods. Please take a look the implimentation in this example and tell me how you would weigh each of our solutions in strengths/weaknesses --- with the goal in mind of course to share models across controllers.

You will see there is a lot of data manipulation to tweak model so it's ready for the view. I feel like a more complex example is going to serve us better for discussing what the best method is for solving this problem.

https://github.com/gigablox/angular-imgur-gallery
http://run.plnkr.co/plunks/akHTslTdRMvfe3KrnPeO/

Simply great examples. Very useful, thanks a lot.

Thank you very much, this is very enlightening!

I also recommend people to take a look at angular.js source code to understand it better, most specifically, search for the createInjector function, that's the one who hold all the logic of Angular DI, services, factory, services, etc.!

You can't inject a service in app.config(), so if you want to pass a service to the provider just inject it in $get:

app.provider('settings', function () {
    this._settings = {};

    this.$get = ['cache', function (cache) {
        var settings = new Settings(cache);

        settings.setSettings(this._settings);

        return settings;
    }];

    this.setSettings = function (settings) {
        this._settings = settings;
    };
});

@doup you say that we can inject service in $get. Can I inject $cookieStore in $get ?

Finally, I understand it

Thank you for the great examples!

What I see is different ways of doing the same thing so far. Can I get an example where one MUST use a service for instance? When using a factory doesnt cut it and you have to use a provider?

Most of the examples above give you a use case for a provider:

look in the first example how you can call setName() on the provider to configure the service. It's under "//hey, we can configure a provider!"

Service is singleton and simple version of Factory. While Factory is a simple version of Provider, Factory is a more flexable compared to service method, and a short handed for configuring a service when $get method is required. Provider creates new object by the $get factory function. Provider is not injectable during run phase or run time while all others are ( Constant, Variable, Service, and Factory), however, Provider is injectable during the configuration phase or compile time.

Provider should be used very sparely as you want to use compile time injection. Usually, Service does most of the job while Factory can deal with more sophisticated logic. Remember, Service is a singleton so if you need to create new object every time, use Factory instead.

Here is a very simple example of provider without 'this':
http://jsbin.com/xolom/2/edit

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.