How to get value of nested constants in angularjs?

1.2k Views Asked by At

I've been trying to get the value of the nested constants inside the angular constants using angular filter. But I can't find an efficient way to get the values. I'm allowed to use lodash "^2.4.1" and i tried using _.pick but still i could only access the root level constants and not the nested ones.

//consider this
angular.module('myApp',[])

.constants('appConstants', {
    CONS1: 'root',
    CONS2: {
          NEST1: 'nested cons1',
          NEST2: 'nested cons2',
    }
)
.filter(getConstants, function  () {
    return function  (input) {
        var value =  appConstants[input];
        if (! value) {
            var keys = input.split('.');
            value =  appConstants;
            angular.forEach(keys, function(key, index) {
                value = value[key];
            });
        }
        return value;
    }
});

//where as
appConstants[CONS1]; //works
appConstants[CONS2.NEST1]; // return undefined
//in lodash
_.pick(appConstants, 'CONS2.NEST1'); // returns empty object
3

There are 3 best solutions below

4
On BEST ANSWER

You also have the option of using the Angular $parse function. I think this will work if you provide it with your root constant object as the context parameter.

That might look something like:

$parse(input)(appConstants)
6
On

Using AngularJS constants

An AngularJS constant is just the value (here an object) it is defined to be.

{
    CONS1: 'root',
    CONS2: {
          NEST1: 'nested cons1',
          NEST2: 'nested cons2',
    }
}

To get NEST1, use the usual property accessors, the dot notation appConstants.CONS1.NEST1 or the bracket notation appConstants["CONS1"]["NEST1"].


Accessing the constants in the HTML template

The simplest way is just to add the constant object into the $rootScope.

angular.module('myApp', [])
    .constants('appConstants', {
        CONS1: 'root',
        CONS2: {
            NEST1: 'nested cons1',
            NEST2: 'nested cons2',
        }
    })
    .run(function($rootScope, appConstants) {
        $rootScope.CONSTANTS = appConstants;
    });

And in any template, just use CONSTANTS as an object.

<span>{{ CONSTANTS.CONS2.NEST1 }}</span> 

Source: Can I directly access module constant from HTML under AngularJS


Using Lodash

If you really want to use lodash, use the _.get function which enables complex path to resolve to the right nested object.

_.get(appConstants, "CONS1.NEST1");

So a filter could be as simple as:

.filter("const", function() {
    return function(input) {
        return _.get(appConstants, input);
    };
});

Pass a string path to the filter to get a value.

{{ "CONS2.NEST1" | const }}

Built-in alternative to Lodash

Amy Blankenship presents Angular's $parse in her answer which, in my opinion, is a better approach than Lodash in this case.


I can't use _.get because I'm allowed to use the older version of lodash 2.4.1.

There are two options:

_.get is quite complex, but for our simple case, a simple string split on dots would probably do.

.filter("getConstants", function() {
    return function(input) {
        var obj = appConstants,
            path = input.split('.'),
            index = 0,
            length = path.length;

        while (obj != null && index < length) {
            obj = obj[path[index++]];
        }
        return obj;
    };
});
1
On

You've forgotten closing brace ( '}' ) in the constant declaration.

Maybe try this :

.constants('appConstants', {
    CONS1: 'root',
    CONS2: {
          NEST1: 'nested cons1',
          NEST2: 'nested cons2',
    }
})