'Updating nested object by path in javascript
Let's say I have this object:
{
categories: [
{ name: "My Category", products: [ { name: "My Product", price: 15 }] },
{ name: "Another", products: [ { name: "Movie", price: 25 }, { name: "Cartoon", price: 7.5 } ] },
{ name: "Lastly", subcategories: [
{ name: "Food", products: [ { name: "Avocado", price: 1.25} ] }
]
}
]
}
I'd like to be able to update the price in this object through a function call as follows:
update(object, "categories/0/products/0",25)
// this would change first product in first category
This answer Javascript: how to dynamically create nested objects using object names given by an array is good but does not address the case when there are arrays in the object.
Underscore acceptable.
Note: this answer Javascript: how to dynamically create nested objects INCLUDING ARRAYS using object names given by an array does not cut it because I don't have array references in that form (products[1])
Solution 1:[1]
I do this, maybe it can help.
const updateObjectValueByPath = ({ arrayPath, data, value }) => {
const key = arrayPath[0];
if (Array.isArray(data) && data !== null) {
if (arrayPath.length > 1) {
return data.map((el, index) => {
if (index === key) {
return updateObjectValueByPath({
arrayPath: arrayPath.slice(1, arrayPath.length),
data: el,
value,
});
}
return el;
}, []);
}
return [...data, value];
}
if (typeof data === 'object' && !Array.isArray(data) && data !== null) {
if (arrayPath.length > 1) {
return {
...data,
[key]: updateObjectValueByPath({
arrayPath: arrayPath.slice(1, arrayPath.length),
data: data[key],
value,
}),
};
}
return { ...data, [key]: value };
}
return data;
};
const data = {
categories: [
{ name: "My Category", products: [ { name: "My Product", price: 15 }] },
{ name: "Another", products: [ { name: "Movie", price: 25 }, { name: "Cartoon", price: 7.5 } ] },
{ name: "Lastly", subcategories: [
{ name: "Food", products: [ { name: "Avocado", price: 1.25} ] }
]
}
]
};
const arrayPath = ['categories', 0, 'products', 0, 'price'];
const value = 25;
const newData = updateObjectValueByPath({data, value, arrayPath});
console.log({newData});
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | jeremydelacasa |
