I'm creating a feature that provides a get() and set() function to read and update values from a JavaScript object. The trick is that I'm using a dot notated string to specify the properties.
I've got the get() working fine, it's the set() that I'm having troubles with.
Sample data:
var data = {
person: {
name: 'Fred',
birthday: '19840101',
address: {
street: '123 Main St.',
city: 'Anytown',
state: 'NY',
zip: '123123'
},
family: {
spouse: 'Sally',
children: ['Sam', 'Frank', 'Susan']
}
}
};
get() function:
function get (path) {
var parts = path.split('.'),
tmp = data;
for (var i = 0, l = parts.length; i < l; ++i) {
if (tmp[parts[i]]) {
tmp = tmp[parts[i]];
}
else {
tmp = null
break;
}
}
return tmp;
}
console.log(get('person.name')); // Fred
console.log(get('person.family.children')); // ['Sam', 'Frank', 'Susan']
console.log(get('person.jobs.apple')); // null
set() function:
var foo = null;
function set (path, val) {
var parts = path.split('.')
tmp = {},
foo = data;
for (var i = 0, l = parts.length; i < l; ++i) {
if (tmp[parts[i]]) {
tmp = data[parts[i]];
}
else {
tmp = {};
}
if (i+1 === l) {
tmp = val;
}
data[parts[i]] = tmp;
}
}
set('person.name', 'Dave'); // replace existing name
set('person.family.children', ['Tim', 'Matt', 'Kathy']); // replace existing array
set('person.jobs.apple', 'developer'); // should create the necessary properties
console.log(data);
I end up with the following object:
obj = {
person: {},
name: "Dave",
family: {},
children: ["Tim","Matt","Kathy"],
jobs: {},
apple: "developer"
}
Any thoughts on how to accomplish this?
It appears that you have some typos in your
set
code.The line
tmp = data[parts[i]];
should really betmp = tmp[parts[i]];
. And then you probably want to put that into a new variable - say,newTmp
, - so that you can assign it back into the object later:Your problem seems to be the data[parts[i]] = tmp; at the end of the set function.
You do not really need any functions at all for this.
See this
There is also this answer which may help
Javascript object key value coding. Dynamically setting a nested value