As the title suggests I have a deeply nested object.
My scenario is my source dataset is the default object/config of my child component. Now when one needs to use anywhere in the project they can change the config according to their needs.
What I am currently doing is spreading the whole object first then changing the necessary object which I am aware is a bad practice. I need to make the config/object more flexible.
From the parent component one will only send the values they want to change and inside the child component I will only update those values which were changed and will keep other properties as it is.
My source dataset:
sourceDataset = {
height: 100,
width: 100,
showHint: {
enable: true,
format: 'test',
},
primary: {
title: 'Primary Title',
style: {
color: 'red',
size: 24
}
},
secondary: {
title: 'Second Title',
min: 0,
max: 0,
style: {
color: 'blue',
size: 54
}
}
}
Example type of object which I might receive from parent component
secondary = {
height: 50,
showHint: {
enable: false
},
primary: {
title: 'Primary Title 2',
style: {
size: 45
}
},
secondary: {
style: {
color: 'green'
}
}
}
Expected Output
result = {
height: 50, // changed
width: 100,
showHint: {
enable: false, // changed
format: 'test',
},
primary: {
title: 'Primary Title 2', // changed
style: {
color: 'red',
size: 45 // Changed
}
},
secondary: {
title: 'Second Title',
min: 0,
max: 0,
style: {
color: 'green', // changed
size: 54
}
}
}
CodePudding user response:
It seems that one way of doing this, is like below, using a recursive function :
let sourceDataset = {
height: 100,
width: 100,
showHint: {
enable: true,
format: 'test',
},
primary: {
title: 'Primary Title',
style: {
color: 'red',
size: 24
}
},
secondary: {
title: 'Second Title',
min: 0,
max: 0,
style: {
color: 'blue',
size: 54
}
}
};
let secondary = {
height: 50,
showHint: {
enable: false
},
primary: {
title: 'Primary Title 2',
style: {
size: 45
}
},
secondary: {
style: {
color: 'green'
},
info: {
text:"lorem ipsum"
}
}
}
function callRecursiveAgain(sourceKey,changedDataKey){
if(sourceKey &&
changedDataKey &&
typeof sourceKey == "object" &&
typeof changedDataKey == "object" &&
!Array.isArray(sourceKey) &&
!Array.isArray(changedDataKey) &&
Object.keys(changedDataKey).length>0 &&
Object.keys(sourceKey).length>0
){
return true;
}
return false;
}
function replaceChangesRecursively(source,changedData){
Object.keys(changedData)?.map(key=>{
if(callRecursiveAgain(source[key],changedData[key])){
replaceChangesRecursively(source[key],changedData[key]);
}
else{
source[key] = changedData[key];
console.log(`${key} ---> changed`);
}
})
}
replaceChangesRecursively(sourceDataset,secondary);
console.log(sourceDataset); //newSouceDataset