How to Update Nested Properties by String In JavaScript
To dynamically update nested object properties in JavaScript by defining the path with a string, you can use the following helper function:
const setProperty = (obj, path, value) => {
const [head, ...rest] = path.split('.')
return {
...obj,
[head]: rest.length
? setProperty(obj[head], rest.join('.'), value)
: value
}
}
Then simply pass your object as the first parameter to the function, your path as a string as the second parameter, and the value you want to assign to the property as the third parameter. For example:
const obj = {
property: {
updated: false
}
}
const updatedObj = setProperty(obj, 'property.updated', true)
// The above will return:
{
property: {
updated: false
}
}
This function is pure, meaning your original object will not be changed. Instead, the function returns with a brand new modified object.
How the function works
This function makes use of recursion to find and update the correct property. We first split up the passed path by dots, and then use destructuring to grab the first value from the array, and all of the rest using spread.
const [head, ...rest] = 'updating.nested.property'.split('.')
// The above will be:
head = 'updating'
rest = ['nested', 'property']
The next step is to return a new object, where we first pass in the existing object with spread, and also dynamically update the property for the head
variable. In the above case obj.updating
would be updated.
The question is, what should be its value? Here is where we can use recursion. We can check if the rest
variable still has any length (not an empty array), and if so, we can recall the function with the new parameters.
// Starting with:
const [head, ...rest] = 'updating.nested.property'.split('.')
// The above will be:
head = 'updating'
rest = ['nested', 'property']
setProperty(obj[head], rest.join('.'), value)
// The above translates to:
setProperty(obj.updating, 'nested.property', value)
// In the next iteration:
const [head, ...rest] = 'nested.property'.split('.')
// The above will be:
head = 'nested'
rest = ['property']
setProperty(obj.nested, 'property', value)
And so on, until we reach the final property, in which case, we stop the recursion and simply set the value.
It's also worth noting that if the root property exists, but the nested properties do not, it will create the object for you and set the path anyway. This will however won't work if the root property does not exists on the object.
const obj = {
property: {
updated: false
}
}
// βοΈ This will work (Adds unkown: { path: 'π' } to the object)
setProperty(obj, 'property.unkown.path', 'π')
// β This will not (Cannot read properties of undefined)
setProperty(obj, 'setting.unkown.path', 'π')
Rocket Launch Your Career
Speed up your learning progress with our mentorship program. Join as a mentee to unlock the full potential of Webtips and get a personalized learning experience by experts to master the following frontend technologies: