Easy way to set javascript object multilevel property?

Viewed 14150

I am trying to create a javascript object like

var allUserExpiry={};
allUserExpiry[aData.userId][aData.courseId][aData.uscId] = aData;

But I am getting an error like allUserExpiry[aData.userId] undefined.

Is there a way, whereby I can set multi-level JS-Object keys? or is it important that I should go by doing allUserExpiry[aData.userId]={}, then allUserExpiry[aData.userId][aData.courseId]={} ?

Please let me know if there are any utility functions available for the same.

10 Answers

Simply use loadash,

let object = {};
let property = "a.b.c";
let value = 1;
_.set(object, property, value); // sets property based on path
let value = _.get(object, property, default); // gets property based on path

Another solution using reduce function (thanks Brian K).

Here we created a get/set to general proposes. The first function return the value in any level. The key is splited considering the separator. the function return the value refered from last index in the key's array

The second function will set the new value considering the last index of the splited key

the code:

    function getObjectMultiLevelValue(_array,key,separator){
        key = key.split(separator || '.');
        var _value = JSON.parse(JSON.stringify(_array));

        for(var ki in key){
                _value = _value[key[ki]];
        }
        return _value;
    }

    function setObjectMultiLevelValue(_array,key,value,forcemode,separator){
        key.split(separator || '.').reduce(function(prev, currKey, currIndex,keysArr) {
            var newObj = {};
            if(prev[currKey] && !forcemode){
                newObj = prev[currKey];
            }
            if(keysArr[keysArr.length-1] == currKey){
                newObj = value;
                prev[currKey] = newObj;
            }

            prev[currKey] = newObj;
            return newObj;
        }, _array);
        return _array;
    }

//testing the function
//creating an array
    var _someArray = {a:'a',b:'b',c:{c1:'c1',c2:{c21:'nothing here...'}}};
//a multilevel key to test
    var _key = 'a,a1,a21';
//any value
    var _value = 'new foo in a21 key forcing replace old path';

//here the new value will be inserted even if the path exists (forcemode=true). Using comma separator
    setObjectMultiLevelValue(_someArray,_key,_value,true,',');
    console.log('_someArray:');
    console.log(JSON.stringify(_someArray));

//inserting another value in another key... using default separator
    _key = 'c.c2.c21';
    _value = 'new foo in c21 key';
    setObjectMultiLevelValue(_someArray,_key,_value);
    console.log('_someArray:');
    console.log(JSON.stringify(_someArray));

//recovering the saved value with different separators
    _key = 'a,a1,a21';
    console.log(getObjectMultiLevelValue(_someArray,_key,','));
    _key = 'c.c2.c21';
    console.log(getObjectMultiLevelValue(_someArray,_key));

Related