M4rk
M4rk

Reputation: 2272

node.js set property from string property name

I was trying to create a function able to set a certain value of an object, having the "path" of the property:

reflectionSet = function(obj, propString, value) {
    var current = obj;
    var splitted = propString.split('.');
    splitted.forEach(function(k) {
        current = current[k];
    })
    current = value;
}
var test = {
    a: {
        s: 'asd',
        g: 'asasdasdd'
    }
};

reflectionSet(test, 'a.g', "otherValue");

and it should become:

{
    a: {
        s: 'asd',
        g: 'otherValue'
    }
}

Unfortunately this doesn't work at all.. Thanks

Upvotes: 0

Views: 3234

Answers (2)

thefourtheye
thefourtheye

Reputation: 239513

You can use split the properties based on . and then using Array.prototype.reduce, get to the inner most part of the Object and update it like this

function reflectionSet(obj, propString, value) {
    return propString.split(".").reduce(function(result, part, index, array) {
        if (index === array.length - 1) {
            result[part] = value;
            return obj;
        }
        return result[part];
    }, obj);
}

var test = {
    a: {
        s: 'asd',
        g: 'asasdasdd'
    }
};

console.log(reflectionSet(test, 'a.g', "otherValue"));

Output

{
    a: {
        s: 'asd',
        g: 'otherValue'
    }
}

Upvotes: 1

techfoobar
techfoobar

Reputation: 66673

This corrected version of your function should do it.

reflectionSet = function(obj, prop, value) {
    prop = prop.split('.');
    var root = obj, i;
    for(i=0; i<prop.length; i++) {
        if(typeof root[prop[i]] == 'undefined') root[prop[i]] = {};
        if(i === prop.length - 1) root[prop[i]] = value;
        root = root[prop[i]];
    }
    return obj;
};

Now:

var test = { a: { s: 'asd', g: 'asasdasdd' } };
reflectionSet(test, 'a.g', "otherValue");

Will return { a: { s: 'asd', g: 'otherValue' } }

Upvotes: 1

Related Questions