-1

How do I pass the value of a constant from one module to another? Thank you in advance. Here's the Plunker demo. The constant "config" is defined in app.module.js, and I want to be able to pass it to the child.module.js for defining constant "childConfig". Right now the console is saying "config is not defined".

Thank you very much in advance.

// app.module.js
(function(){
    "use strict";

    var myApp = angular
        .module("myApp", ["child"]);

    myApp.constant("config", {
        rootURL: "components/"
        , version: "myApp1.0.0"
    })
})();

// app.component.js
(function(){

    "use strict";

    // Define controller
    function mainController(){
        this.$onInit = function() {
            var mainVM = this;

            mainVM.parent = {
                "lastName": "Smith"
                , "firstName": "Jordan"
            };
        };

    }

    // Define component
    var mainComponent = {
        controller: mainController
        , controllerAs: "mainVM"
    };

    // Register controller and component
    angular.module("myApp")
        .controller("mainController", mainController)
        .component("mainComponent", mainComponent);

})();

//components/child.module.js
(function(){
    "use strict";

    var child = angular.module("child", []);
    
    child.constant("childConfig", config);

})();

//components/child.component.js
(function(){
    "use strict";

    // Define controller
    function childController(config) {
        this.$onInit = function() {
            var vm = this;
            
            vm.getTemplateUrl = function(){
              return config.rootURL + 'child.html';
            }
            vm.rootURL = config.rootURL;
            vm.version = config.version;
            vm.child = {
              "firstName": "Jack"
            }
        };
        // end of $onInit()
    }

    // Define component
    var child = {
        //templateUrl: vm.getTemplateUrl + "child.html"
        //templateUrl: "components/child.html"
        template: "<ng-include src='vm.getTemplateUrl()'/>"
        , controller: childController
        , controllerAs: "vm"
        , bindings: {
            parent: "<"
        }
    };


    // Register controller and component
    angular.module("child")
        .controller("childController", childController)
        .component("child", child);

})();
<!DOCTYPE html>
<html>

  <head>
    <script src="//code.angularjs.org/snapshot/angular.js"></script>
    <link rel="stylesheet" href="style.css">
    <script src="app.module.js"></script>
    <script src="app.component.js"></script>
    <script src="components/child.module.js"></script>
    <script src="components/child.component.js"></script>
  </head>

  <body ng-app="myApp" ng-controller="mainController as mainVM">
    Parent: {{mainVM.parent.firstName}} {{mainVM.parent.lastName}}<br>
    <child parent="mainVM.parent"></child>
  </body>

</html>
Telly Ipock
  • 133
  • 3
  • 12
  • 1
    What's the point of defining the same constant twice? Just inject the config constant wherever you need it. – JB Nizet Sep 19 '17 at 18:48
  • No I'm not defining the same constant twice. The actual app I'm working on is much bigger and have many levels. I need to use the parent constant in each child constant's definition, so they can be used in their own controllers. And when I update the rootURL, all the child URLs will be changed. I've updated the Plunker to demonstrate that. – Telly Ipock Sep 19 '17 at 19:13
  • Don't define a constant for your child configs. Define a service, where you can inject the root constant, and return an object containing fields whose value depend on the injected constant. – JB Nizet Sep 19 '17 at 19:16
  • That makes sense. Thank you. – Telly Ipock Sep 20 '17 at 12:58

1 Answers1

2

I think you might've misunderstood the constant factory's capabilities. It's not supposed to be mutable neither variable, therefore it won't be able to use another external provider to compose it's value, it'll only serve a plain value that is pure.

On the other hand, if you don't mind, a factory can be use to achieve the result your are looking for. Basically you can create a factory that fabricate a string for you based on the injected config provider.

For example:

child.factory("childConfigURL", ['config', function(config) {
    return config.rootURL + "/component/";
}]);

The only problem with this approach is that it can't be injected into a module configuration function, because it's not pure anymore and needs to be bootstrapped to resolve it's dependencies.

Note on constants:

constant(name, value);

Register a constant service with the $injector, such as a string, a number, an array, an object or a function. Like the value, it is not possible to inject other services into a constant.

But unlike value, a constant can be injected into a module configuration function (see angular.Module) and it cannot be overridden by an AngularJS decorator.

Ref.: $provide.constant

lenilsondc
  • 9,590
  • 2
  • 25
  • 40