0

I create a provider to retrieve configuration of application via a Json file. Then i use it in my application.config to instiante route from this configuration object.

    MyApp = angular.module('MyApp', ['MyAppControllers','LocalStorageModule','ui.router']); 

This is the code of my configuration provider :

    MyApp.provider('$configuration', function() {
    return {
    $get : function($http,localStorageService) {
        return {
            getConfiguration:function() {       
                var config = localStorageService.get("configuration");
                console.log(config);
                if(config ==null || config == undefined) {

                    xhr = GetHttpRequest();                    
                    xhr.onreadystatechange = function () {     
                        if (xhr.readyState == 4) {                            
                            if (xhr.status == 200 || xhr.status == 304) {
                                localStorageService.set("configuration",xhr.responseText);
                                config = xhr.responseText;  
                            } else {
                                console.log('## Error loading configuration');
                            }
                        }
                    }
                    xhr.open('GET','/assets/js/My/config.json',false);      
                    xhr.send(null);
                    return JSON.parse(config);
                } else {
                    return config;
                }    
            }
        }
    }
    }

});

Here the code of my routes configuration :

MyApp.config(['$stateProvider', '$urlRouterProvider','$configurationProvider',
    function ($stateProvider, $urlRouterProvider,$configurationProvider) {

    console.log($configurationProvider);

    configuration=$configurationProvider.getConfiguration();

    angular.forEach(configuration.url, function(value, key) {     
            $stateProvider.state(stateName,         
                { 
                 url: stateUrl,
                 views: stateView                                
                }
            );   
    });                  
    }        
]);

But chrome give me this error :

[$injector:modulerr] Failed to instantiate module MyApp due to: TypeError: Cannot read property 'get' of undefined

  • Did any of the answers below address your question? If so, consider accepting.. Otherwise, if you have clarifications or comments, please ask. – New Dev May 06 '15 at 19:51

2 Answers2

0

You return the provider context from $get function that should be this.$get the thing which you are following is done when you register provider using $provide service. For more info read my Another Answer here

Provider

MyApp.provider('$configuration', function() {
    this.$get: function($http, localStorageService) {
        return {
            getConfiguration: function() {
                ...code here
            }
        }
    }

});
Community
  • 1
  • 1
Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299
  • I downvoted (sorry I didn't comment in time) because the answer doesn't address the much bigger misunderstanding/problem, and only addresses a relatively minor issue caused by the bigger problem. And also, it took me a while to mentally diff the OP's example and yours - why not substitute the clutter with something like `//... etc.` and clearly show where the difference is? – New Dev May 03 '15 at 07:18
  • @NewDev i think you did the same think with more explaination..I'll edit my answer..Kindly do remove downvote atleast – Pankaj Parkar May 03 '15 at 07:22
  • You have correctly identified the incorrect usage of `.provider`, but missed what the OP's ultimate goal and issue is. – New Dev May 03 '15 at 07:23
  • @newdev I don't see any reason to downvote..If you are getting satisfaction then I'll remove mine answer & will upvote yours. – Pankaj Parkar May 03 '15 at 07:28
  • You'd need to edit the question for the system to allow me to change my vote. But up to you to decide whether you want to keep or delete it – New Dev May 03 '15 at 07:36
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/76798/discussion-between-pankajparkar-and-new-dev). – Pankaj Parkar May 03 '15 at 07:36
  • @NewDev I've updated my answer..could you have review it please? – Pankaj Parkar May 03 '15 at 10:10
0

There are a couple of issues here.

For one, you are incorrectly registering a provider - $configurationProvider. A provider function is used to expose API to configure how a provider provides a service when Angular calls it to create a service.

.provider("$configuration", function configurationProviderFn(){
   this.someConfigurableProperty = "default value";
   this.$get = function actualServiceFactory($http, localStorageService){
      // returns the service instance
      return {
        getConfiguration: function(){...}
      }
   }
});

So, a .provider is used when you want to expose some hooks to configure how a service is created.

But you don't seem to want to do that at all, because what you are attempting to do is to create a service that fetches some configuration (either from local storage or remotely) - and then use that configuration to configure the app.

That would not work.

Angular first runs the config blocks of all the registered modules, and it would not allow injecting a $configuration service (and registering via .provider does not change that one bit).

Moreover, even if you did instantiate a service by actually invoking its provider's $get function, Angular would not wait for an async operation to complete.

It is a rare case when one needs to download a configuration script to configure the Angular application - you should examine whether you really need this. But if you do, one way would be to download it outside of Angular, and then to manually bootstrap Angular.

var appConfig = getConfigration(function onSuccess(){
   var rootEl = document.getElementById("MyApp");
   angular.bootstap(rootEl, ['MyAppControllers', 'LocalStorageModule', 'ui.router']);
});

There are other ways with lazy loading of modules, but that is beyond the scope of this answer.

New Dev
  • 48,427
  • 12
  • 87
  • 129