3

I want to set module.constant according to a tag which is the result of an HTTP request.

Below is the demo code in my project;

code in app.js

(function(){
     var myApp = angular.module('myApp',['ui.router','ui.bootstrap']);

     myApp.contant("API_URL","https://www.helloworld.com/API");

     myApp.run(function($rootScope.$http){
     some code;
     });  
})();

I want to config a special Id according to the result of an HTTP request like this;

$http.get(API_URL + "/configTag")
  .then(function success(response){
      var tag = response.data.tag;
      if(tag === 0) {
      myApp.constant("specialID","111111111");
      } else if (tag === 1) {
      myApp.constant("specialID","222222222");
      } else {
      myApp.constant("specialID","333333333");
      }  
  },function error(response){

  }); 

But I am new to front end and AngularJS. I don't know how to realize this?

6
  • What error are you getting? Commented Nov 2, 2016 at 3:30
  • 4
    To do this in a general manner is tough. Using $http is difficult because it isn't really available until the app is running, but at that point it is too late to set constants. Why does the value need to be stored in a constant? A simpler solution would be to have a service that returns a cached promise that exposes the constant. Commented Nov 2, 2016 at 3:33
  • @ShashankAgrawal I tried to put the code in the myApp.run , and and got a injection failed error Commented Nov 2, 2016 at 4:03
  • @pgreen2 mm, in case to use the constant globally, and we have different specialID according to the hostname. Commented Nov 2, 2016 at 4:11
  • 1
    you can just inject the service wherever you need to use the constant - or even just set the constant right on $rootScope ... as it has been pointed out, it is not possible to set an actual angular constant during the main run loop. I do this approach in my app where the app's config is retrieved asynchronously at the start of execution - I set it in a $rootScope.config object. It is also nice to do something like: $rootScope.$broadcast('App:Config', $rootScope.config); Commented Nov 2, 2016 at 4:49

2 Answers 2

2

Short answer: The $http service can't be used to create Angular constants.

The AngularJS framework operates in two phases: the "config" phase and the "run" phase. Once the "run" phase starts, providers can no longer be configured and constants can no longer be added. $http service operations can only be done in the "run" phase.

However a service provider can provide a promise of a constant:

app.factory("specialIDpromise", function(API_URL, $http) {
    var promise = $http.get(API_URL + "/configTag")
        .then(function success(response){
            var tag = response.data.tag;
            if(tag === 0) {
                //return to chain data
                return "111111111";
            } else if (tag === 1) {
                return "222222222";
            } else {
                return "333333333";
            };  
        }).catch(function error(response){
            //return converts rejection to success
            return "something";
        });
   //return promise to factory
   return promise;
});

To use in a controller:

app.controller("myCtrl", function(specialIDpromise) {
    specialIDpromise.then(function(specialID) {
        console.log(specialID);
        //Do other things that depend on specialID
   });
});

All operations in the config phase need to be synchronous (including adding constants.) Asynchronous operations such as XHRs by the $http service happen in the run phase of an AngularJS app.

Sign up to request clarification or add additional context in comments.

Comments

0

It's possible to do want you want using server side data. You have to inject what modules you need, and run your function to get the data in a document.ready function. Here is how I am doing it, but the only issue I'm having is if the server is unreachable; then the app doesn't get bootstrapped. I placed this code in my app.js file outside of the angular.module code, as it will not work there since the app hasn't been bootstrapped yet.

angular.element(document).ready(function () {
    getConstants();
});

//Get constants from server and manually bootstraps application to the DOM
function getConstants() {    
    var initInjector = angular.injector(["ng"]);
    var $http = initInjector.get("$http");

    $http.get('urlThatRetrievesConstants').then(function (result) {

        /*Below I'm setting the constants on the app module and giving them a 
        name, which will be used to reference in whatever modules you will use it 
        in */

        angular.module('appModuleName').constant('constantsName', result.data);

        /*Here I'm bootstrapping the app*/
        angular.bootstrap(document, ["appModuleName"]);   

    }, function (error) {      
  /*Handle server errors from request*/
    });
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.