0

I have a nested default object that I want to both extend and overwrite with nested properties. I tried with the spread operator but you can also use Ojbect.assign.

The problem is that nested objects get overridden instead of their respective properties getting overridden and/or extended.

const defaultOptions = {
  a: 0,
  b: 1,
  c: {
    hello: 'world',
    age: 20
  }
};

const specialOptions = {
  b: 0,
  c: {
    age: 10
  },
  d: 1
};

const options = {
  ...defaultOptions,
  ...specialOptions
}
console.log(options)


const expectedOptions = {
  a: 0,
  b: 0,
  c: {
    hello: 'world',
    age: 10
  },
  d: 1
}
console.log(expectedOptions)

Update 2021-08-24

It seems this question is a duplicate of another so therefore I will delete it.

Nermin
  • 749
  • 7
  • 17

1 Answers1

0

Here is a recursive solution, although it mutates the input object and doesn't return a new one, as I would've wanted. Hence why I added the deepCopy function.

Also, the order isn't maintained. But I assume that isn't of the biggest concern if you are using objects in the first place.

const defaultOptions = {
  a: 0,
  b: 1,
  c: {
    hello: 'world',
    age: 20
  }
}
const specialOptions = {
  b: 0,
  c: {
    age: 10
  },
  d: 1
}

const deepCopy = obj => JSON.parse(JSON.stringify(obj))

const options = deepCopy(specialOptions)

const extendObj = (defaults, obj) => {
  Object.entries(defaults)
    .forEach(([key, value]) => {
      if (obj[key] === undefined) {
        obj[key] = value
      } else if (typeof value === 'object') {
        extendObj(defaults[key], obj[key])
      }
    })
}

extendObj(defaultOptions, options)
console.log(options)
Nermin
  • 749
  • 7
  • 17