I have an object like:
{
categories: {
Professional: {
active: false,
names: [
{
id: 1,
name: "Golf",
active: false
},
{
id: 2,
name: "Ultimate Frisbee",
active: false
}
]
}}
and i want update categories.Professional.active
with true
, into the reducer i have:
return {
...state,
categories: {
...state.categories,
Professional: {
...state.categories.Professional,
active: true
}
}
}
now i want write a function for spreadfy an object and update a single property by json path. Eg.
return deepPatch(state, 'categories.Professional.active', true);
the goal for the function deepPatch
is build at runtime this structure:
return Object.assign({}, obj, {
categories: Object.assign({}, state.categories, {
Professional: Object.assign({}, state.Professional, {
active: true
})
})
});
i have tried but don't know how make a recursive spread:
function deepPatch(obj: any, path: string; value: any){
const arrayPath: string[] = path.split('.');
const currObj = null;
for (let i = 0, e = arrayPath.length; i < e; i++) {
const currPath = arrayPath[i];
currObj = obj[currPath];
currObj = Object.assign({}, currObj, ???);
}
return currObj;
}
You could get the first key and create a new object by calling the function again until no more keys are available.
function deepPatch(object, path, value) {
var [key, rest] = path.match(/^[^.]+|[^.].*$/g);
return { ...object, [key]: rest
? deepPatch(object[key], rest, value)
: value
};
}
var state = { categories: { Professional: { active: false, names: [{ id: 1, name: "Golf", active: false }, { id: 2, name: "Ultimate Frisbee", active: false }] } } },
result = deepPatch(state, 'categories.Professional.active', true);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }