Fleeck
Fleeck

Reputation: 1066

Set app.config within a controller

So, I have my app.controller and inside of it I have a request. When request is successful, I want to set retrieved data to some $provider property, i.e.

app.controller('someCtrl', function(){
  app.config(function($someProvider){
    $someProvider.property = response.data;
    $someProvider.function(response.data.status);
  })
})

I'm trying to set this within controller, but it does nothing. Any tips, guys? :)

Upvotes: 1

Views: 3434

Answers (3)

Cosmin Ababei
Cosmin Ababei

Reputation: 7072

Your question comes down to how can I postpone angular's bootstrap process until I have some async data.

For the async part, you can use (or do) whatever you want, it doesn't really matter.
Fun fact: You can even use $http before bootstrapping angular just by getting it via angular.injector(["ng"]).get("$http");.

This being said, when you have all your async data, all that's left to do is to bootstrap angular. This can be achieved via angular.bootstrap - source.

Here's a working example in which I asynchronously attach a controller (remember, you can do whatever you want: attach various constants, config blocks, etc). I've used setTimeout for simplicity's sake.

// Initial Angular Code
angular.module('myApp', []);

// Async function. I've used setTimeout for simplicity's sake
setTimeout(function() {
  angular
    .module('myApp')
    .controller('MyCtrl', ['$scope',
      function($scope) {
        $scope.value = 'Angular has started!';
      }
    ]);

  // Boostrap AngularJS
  angular.bootstrap(document.getElementById('boostrap-me'), ['myApp']);
}, 1000);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>

<div id="boostrap-me" ng-controller="MyCtrl">
  <div ng-bind="value">Angular hasn't yet bootstrapped as we're waiting for some async data!</div>
</div>

Upvotes: 1

Estus Flask
Estus Flask

Reputation: 223288

Newly added config blocks aren't executed after the ending of config phase, the same applies to other app methods because they result in additional config blocks internally.

It is possible with:

app.config(($provide, $someProvider) => {
  $provide.value('$someProvider', $someProvider);
});

app.controller('someCtrl', ($someProvider) => {
  $someProvider...
});

This voids the warranty and may indicate XY problem that should be solved the other way, depending on what $someProvider is and how it functions.

If $some is injected and used before setting $someProvider, this will result in race condition. If $some was changed at some point to not watch for $someProvider properties after instantiation, this will result in breaking changes without notice that will make the tests fail.

It is acceptable for badly designed third-party services that don't cause ill effects when being treated like that. And as any other hack, it should be thoroughly covered with tests.

Upvotes: 2

neuronet
neuronet

Reputation: 1159

if default injecting doesn't do the job maybe store your provider at config time to some other variable and use this var in controller later

but angular says:

During application bootstrap, before Angular goes off creating all services, it configures and instantiates all providers. We call this the configuration phase of the application life-cycle. During this phase, services aren't accessible because they haven't been created yet.

Once the configuration phase is over, interaction with providers is disallowed and the process of creating services starts. We call this part of the application life-cycle the run phase.

so i don't know if this will work

Upvotes: 2

Related Questions