Hoff
Hoff

Reputation: 39836

Merge 2 nested objects / overwrite selectively in ES6

I'm looking for a way to merge 2 nested objects in ES6, so that one object selectively overwrites only the properties it defines. Let me explain by example:

baseObject = {
  style = {
    background: 'yellow',
    text: {
      color: 'black',
      fontSize: 20,
    }
  }
}

overwritingObject = {
  style: {
    text: {
      fontSize: 12,
    }
  }
}

The desired outcome is this:

mergedObject = {
  style = {
    background: 'yellow',
    text: {
      color: 'black',
      fontSize: 12 <---- only this was overwritten
    }
  }
}

I've looked at native JS' object.assign and lodash's extend, assign, and merge methods, but none of them seem to fit the bill (if I'm not mistaken).

Upvotes: 1

Views: 212

Answers (3)

fyasir
fyasir

Reputation: 2970

You can use lodash.merge function as mentioned above or you can write your own deep merge function

function mergeDeep(target, source) {
  if (target && source) {
    Object.keys(source).forEach(key => {
      if (typeof source[key] === 'object') {
        if (!target[key]) Object.assign(target, { [key]: {} });
        mergeDeep(target[key], source[key]);
      } else {
        Object.assign(target, { [key]: source[key] });
      }
    });
  }
  return target;
}

const baseObject = {
  style: {
    background: 'yellow',
    text: {
      color: 'black',
      fontSize: 20,
    }
  }
}

const overwritingObject = {
  style: {
    text: {
      fontSize: 12,
    }
  }
}

console.log(mergeDeep(baseObject, overwritingObject))

Upvotes: 1

squirrelsareduck
squirrelsareduck

Reputation: 884

This just follows up on frodo's answer with an image of it in action, confirming the solution.

enter image description here

Upvotes: 1

frodo2975
frodo2975

Reputation: 11745

Lodash's merge looks like it should do exactly what you're looking for:

mergedObject = _.merge(baseObject, overwritingObject);

https://lodash.com/docs/4.17.15#merge

Upvotes: 3

Related Questions