12

I have written a module in angularJS that encapsulates all the backend communications. For greater flexibility I have the api prefix as a constant value on the module (could be value since I am not using it in the config phase). so something like

angular.module('myapp.data').constant('apiPrefix', '/api/data');

Now I want to use this module from two different applications. One uses /api1/data and the other one /api2/data and I would like to change this during the config phase of the application. I know how to do that with a provider, but having a provider to hold a value seems like an overkill to me. Can I modify used modules constants or values from the application config phase?

something like:

angular.module("data", [])
.value('apiPrefix', '/api/data')
.factory('display', function(apiPrefix){
  return {
    pref: function(){
      console.log(apiPrefix);
      return apiPrefix;
    }
  }
});


angular.module("myApp",['data'])
.config(['apiPrefix', function(prefix){
  prefix = 'https:/api/data'; 
}])
.controller("Example", function($scope, display) {
   $scope.prefix = display.pref;
});
5
  • 1
    Not sure but you can try to do it at run stage. Commented Apr 9, 2014 at 16:03
  • Yeah you can update a value at the run stage, and you can inject a constant in config but since it's a constant it can't be changed stackoverflow.com/questions/13035568/… Commented Apr 9, 2014 at 16:06
  • So what you are saying is that it should be a value instead of a constant in the module and modify it on run stage of the application instead of the config? Commented Apr 9, 2014 at 16:09
  • Why don't you give it a try :) Commented Apr 9, 2014 at 16:10
  • Indeed that is what we're saying. Config needs to be run on everything that could have config before it is injected into anything hence the problem. Commented Apr 9, 2014 at 16:10

3 Answers 3

12

to override the module values, you can redefine the angular value in later modules. I believe it should not be done module config time.

angular.module("data", [])
.value('apiPrefix', '/api/data')
.factory('Display', function(apiPrefix){
  return {
    pref: function(){
      return apiPrefix;
    }
  }
});




angular.module('myapp', ['data'])
  .value('apiPrefix', '/api2/data')
  .controller('MainCtrl', function($scope, Display)    {
      $scope.name = Display.pref();
  });

see the plunker here: http://plnkr.co/edit/k806WE

same thing is applicable for angular constants too.

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

2 Comments

Great solution. I kind of fill bad that I didn't know that since I could have accidentally override a module constant or value, since I am using them a lot. Good thing I am always trying to create unique descriptive names.
Thanks @mxa055. Actually, I prefer to keep constants and values like configuration or backend api endpoints in a seperate config module.
11

Our module

angular.module("data", [])
  .constant('apiPrefix', '/api/data');

We can override constant fully, like value.

angular.module('myapp', ['data'])
  .constant('apiPrefix', '/api2/data');

also we can override fully in config

angular.module('myapp', ['data'])
    .config(function ($provide) {
        $provide.constant('apiPrefix', '/api2/data');
    });

also we can override fully or partially (if object) in run

angular.module('myapp', ['data'])
    .run(function (apiPrefix) {
        apiPrefix = '/api2/data';
    });

But if we want to override constant with object partially in config (not in run), we can do something like this

angular.module("module1", [])
    .constant('myConfig', {
        param1: 'value1' ,
        param2: 'value2'
    });

angular.module('myapp', ['data'])
    .config(function ($provide, myConfig) {
        $provide.constant(
            'myConfig', 
            angular.extend(myConfig, {param2: 'value2_1'});
        );
    });

2 Comments

Reference myConfig with string to override extend values on module myapp. angular.module('myapp', ['data']) .config(function ($provide, myConfig) { $provide.constant( myConfig, angular.extend('myConfig', {param2: 'value2_1'}); ); });
Thanks. Yes, $provide.constant('myConfig', ... - 'myConfig' must be a string!
1

Angular modules, controllers, etc. can be contained within functions, if-statements, etc. They do not have to be at the top level. So, you could include this in your code:

if (environmentOne()) {
  module.value('apiPrefix','api1/data');
} else {
  module.value('apiPrefix','api2/data');
}

Hope that helps!

2 Comments

This sounds interesting, but I would hate to have to do something like that in my module for every different application that might use me. It short of creates a "dependency" between the module and its users.
Ah, you're right. I misread your question, and thought it was a matter of development/staging/production environments. Khanmizan's answer is better.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.