Home > Mobile >  Compare deeply nested object and save the differences in the default object along with other propert
Compare deeply nested object and save the differences in the default object along with other propert

Time:03-29

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

  • Related