Search code examples
angularjsangular-uiangularjs-service

Angular JS: why the difference between module.config injection and controller injection?


This is something that I could not figure out from digging into the AngularJS code, maybe you can help solve the mystery.

To show it, I added a service to AngularJS seed project:

function MyServiceProvider() {
    console.log('its my service');
    this.providerMethod = providerMethod;

    function providerMethod() {
        console.log('its my service.providerMethod');
    }

    this.$get = $get;

    function $get() {
        var innerInjectable = {
             name: 'stam'
        };
        return innerInjectable;
    }
}

var serviceModule = angular.module('myApp.services', []).
    value('version', '0.1').
    provider('myservice',MyServiceProvider);

You can see that this provider exposes $get and a certain 'providerMethod'.

Now, for the injection usage: If we call config, we can inject the whole class and get access to the 'outer' provider method:

serviceModule.config(function(myserviceProvider) {
    console.log('myServiceProvider:',myserviceProvider);
    myserviceProvider.providerMethod();
});

But when we inject this to a controller (note the Provider-less name), only the $get return value is exposed:

function MyCtrl1(myservice) {
    console.log('MyCtrl1.myservice =',myservice,myservice.name);
}
MyCtrl1.$inject = ['myservice'];

Console output follows as it should: its my service myServiceProvider: Constructor {providerMethod: function, $get: function} its my service.providerMethod MyCtrl1.myservice = Object {name: "stam"} stam

Can any one explain the difference? The reason? many thanks for any thought

Lior

PS: I've seen this technique in angular-ui new ui-router (excellent project!). I need access to the outer provider class to do injection in jasmine and other places - to no avail


Solution

  • From the Angular mailing list I got an amazing thread that explains service vs factory vs provider and their injection usage. I decided to put it in its own question here

    the specific answer is: it is so by design, to allow configuration of the provider at config time.