Rudi
Rudi

Reputation: 1169

Using AngularJS Provider with GET and SET

In my last question I did search a solution to use a value in AngularJS during .config. I learned I have to use a provider. Now I try to set a value using this provider. It seems there is a limitation with providers, I can set something ONLY during .config ? I get the error "TypeError: appState.setState is not a function", but setState is a function, at least for my understanding. I'm wrong?

The code:

angular
    .module('main', [
        'ngRoute'
    ])

    .provider('appState', function(){
        var appState;

        this.setState = function(newState) {
            appState = newState;
        };

        this.getState = function() {
            return appState;
        };

        this.$get = function() {
            return appState;
        };

        function init() {appState='/home';}
        init();

    })
    .config(function($routeProvider, appStateProvider){

        $routeProvider
            .when('/home', {
                templateUrl: "partials/home"
            })
            .when('/info', {
                templateUrl: "partials/info"
            })
            .otherwise({
                redirectTo: appStateProvider.getState()
            })

    })

    .run(function ($rootScope, appState) {

        $rootScope.$on('$routeChangeStart', function (event, next, current) {
            if (next.$$route) {
                appState.setState(next.originalPath); 
                // -> ERROR: "TypeError: appState.setState is not a function"
            }
        })

    })

;

Upvotes: 1

Views: 1224

Answers (1)

Jesus Rodriguez
Jesus Rodriguez

Reputation: 12018

A Provider is like a two-part service, Its minimum form is like a factory:

aModule.provider('foo', function() {
  this.$get = function() {
    return 1;
  }
});

Then you can inject this in any other service, directive, controller and run function:

aModule.controller('BarCtrl', function(foo) { ... });

Notice how I used foo as the name of the provider.

What this does, is inject into the controller what the $get returns. AKA, if you log foo inside the controller you will get 1.

So what's the point of the provider? Being able to configure the service before the app runs.

aModule.provider('foo', function() {
  var appState;

  this.setState = function(newState) {
    appState = newState;
  }  

  this.$get = function() {
    return appState;
  }
});

In this case, apart from the $get function, we have some other functions. How can we use them? We need to inject the provider itself and not the factory within. How can we do that?

aModule.config(function(fooProvider) {
  fooProvider.setState('Hello');
}

Notice how I used this time fooProvider instead of just foo. That says that I am injecting the provider itself. That said, the provider can only be injected into .config functions and other provider's constructors.

Now if you log foo in our controller, we see: hello.

I repeat, what you inject in the controller is what the $get returns and not the other methods outside it. That is why you can't use setState on the run, because what you inject there is what $get returns.

Upvotes: 1

Related Questions