marksomnian marksomnian - 2 months ago 7
Javascript Question

Setting nested object properties with dynamic name

Coming off my previous question (which was about getting the property), I need to set the value of a nested object member using a dynamic property name.



const settings = {
service: {
username: 'foo',
password: 'bar'
}
};

const settingName = 'service.username';
const newValue = 'baz';

settings[settingName] = newValue ; // doesn't work
console.log(settings.service.username); // foo





The only way I can think of is to use eval:

eval(`settings.${settingName} = "${newValue}"`);




const settings = {
service: {
username: 'foo',
password: 'bar'
}
}

const settingName = 'service.username';

const newValue = 'baz';

eval(`settings.${settingName} = "${newValue}"`); // works, but bad

console.log(settings.service.username);





But this has problems (for example, the example above assumes the new value is a string). Is there a way to assign a property of a nested object whose name is not known without using eval?

Answer

You can do it like below,

var settings = {service: {username: 'TEST', password: ''}}
var key = "service.username";

function setValue(obj, keys, val){
  keys.split(".").forEach(function(itm, i, arr){
    if (i == arr.length - 1) obj[itm] = val;
    else obj = obj[itm];
  });
}

setValue(settings, key, "hello");
console.log(settings.service.username); //"hello"
Comments