angularjs - how to reference value defined in same module

324 Views Asked by At

I'm writing a configuration module that includes two .value recipes:

  • baseURL
  • a number of REST api URLs which go on top of the baseURL

I've currently set these up as .value but they could just as easily be .constant

Since I want to be able to change baseURL without having to rewrite all API urls I need to reference the baseURL i've just defined - in the same module:

var configuration = angular.module('configuration', []); 

configuration.value('Config',{
    baseURL : 'http://dev.mysite.com/',     // define Base URL
});

configuration.value('ApiList', {
    getMyDataLink1 : this.baseURL + 'rest/folder1/action1/api_key/',
    getMyDataLink2 : this.baseURL + 'rest/folder2/action2/api_key/',
    getMyDataLink3 : this.baseURL + 'rest/folder3/action3/api_key/',
});

when I test the variables:

  • Config.baseURL outputs correctly as http://dev.mysite.com/
  • ApiList.getMyDataLink1 is only half defined since the this.baseURL part is not defined (ie it outputs undefinedrest/folder1/action1/api_key/ )

I've also tried defining the ApiList .value as:

getMyDataLink1 : Config.baseURL + 'rest/folder1/action1/api_key/', 
//or
getMyDataLink1 : baseURL + 'rest/folder1/action1/api_key/', 

but either of those give an "Uncaught ReferenceError: XXXX is not defined" error...

Is it possible to reference a .value from another .value within the same module ?

EDIT: see http://jsfiddle.net/goredwards/yy5xuodh/

EDIT2: see http://jsfiddle.net/goredwards/xvj5xcgz/ where I've converted the 2nd .value to a .factory - then compare to the js-only method at the bottom of the fiddle - there must be a more concise way than this !?

3

There are 3 best solutions below

0
On BEST ANSWER

as Gaurav pointed out it doesn't seem possible to inject anything into a .value recipe so the shortest and clearest way (from a maintainability perspective) i've found is to convert the concatenating .value recipe (ie the 2nd one) into a .factory recipe and inject the 'Config' .value variable:

var configuration = angular.module('configuration', []); 

configuration.value('Config',{
    baseURL : 'http://dev.mysite.com/',     // define Base URL
});

configuration.factory('ApiList', ['Config', function(Config){
    return{
        getMyDataLink1 : Config.baseURL + 'rest/folder1/action1/api_key/',
        getMyDataLink2 : Config.baseURL + 'rest/folder2/action2/api_key/',
        getMyDataLink3 : Config.baseURL + 'rest/folder3/action3/api_key/'
    };
}]);

while this works (see http://jsfiddle.net/goredwards/xvj5xcgz/), and is relatively succinct & clear, it does seem strange that .values can't simply be concatenated to other .values...

1
On

As far as I know, you cannot inject a value dependency into another value . You can use a service or factory to build your API urls. Something like this:

   configuration.value('Config',{
    baseURL : 'http://dev.mysite.com/',     // define Base URL
});

configuration.value('ApiList', {
    getMyDataLink1 : 'rest/folder1/action1/api_key/',
    getMyDataLink2 : 'rest/folder2/action2/api_key/',
    getMyDataLink3 : 'rest/folder3/action3/api_key/',
});

app.service('URLService', ['Config', 'ApiList', function(Config, ApiList){
    return {
    getURLs : function() {
        var url = Config.baseURL+ApiList.getMyDataLink1;
        return url;
    }
}}]);
1
On

Have you tried injecting Config into ApiList?

     configuration.value('ApiList', function(Config) {
           getMyDataLink1 : Config.baseURL + 'rest/folder1/action1/api_key/',
           getMyDataLink2 : Config.baseURL + 'rest/folder2/action2/api_key/',
            getMyDataLink3 : Config.baseURL + 'rest/folder3/action3/api_key/',
        });