Francisc
Francisc

Reputation: 80445

Configure constant after config phase

I have an Angular constant which I need to configure after the config phase of the app.
It's basically a collection of endpoints, some of which are finalized after the app makes a few checks.

What I am currently doing is returning some of them as functions where I can pass in the part that changes: (Example code, not production code.)

angular.module('...',[]).constant('URL',(function()
{
    var apiRoot='.../api/'
    return {
        books:apiRoot+'books',//No env needed here - Property (good)
        cars:function(env){//But needed here - Method (bad, inconsistent)
            return env+apiRoot+'/cars';
        }
    };
}()));

But that's rather inefficient because I only need to compile that URL once, not each time I need it.

URL.books
URL.cars('dev');

I was thinking of turning it into an Angular provider and configure it prior to instantiation, but I don't know if it's possible to configure it outside the config block, when it would be too early because I don't have env yet for example.

How can I do it?

Upvotes: 2

Views: 175

Answers (1)

Pieter Herroelen
Pieter Herroelen

Reputation: 6066

You could use a promise for each entry (books,cars,...). When you have all info (e.g. env) for the cars entry, you can resolve the promise.

angular.module('...',[]).constant('URL',(function()
{
    var apiRoot='.../api/'

    var carsPromise = function() {
       var deferred = $q.defer();
       getEnv().then(function(env) { // getEnv also returns a promise
          deferred.resolve(env+apiRoot+'/cars');
       });
       return deferred.promise;   
    }

    return {
        books: instantlyResolvedPromise(apiRoot+'books'),
        cars: carsPromise();
    };
}()));

Of course, this adds some complexity as promises tend to spread like a disease but you will end up with a consistent api.

Upvotes: 2

Related Questions