0

I have 2 objects, for example: 1st:

const langs = {
  en: {
    components: {
      test: 'test'
    },
  },
  de: {
    components: {
      test: 'test'
    },
  },
};

2nd:

const langs2 = {
  en: {
    app: {
      test: 'test'
    },
  },
  pl: {
    app: {
      test: 'test'
    },
  },
};

And now i need to merge these 2 object into one, it should looks like:

{
  en: {
    components: {
      test: 'test'
    },
    app: {
      test: 'test'
    },
  },
  de: {
    components: {
      test: 'test'
    },
  },
  pl: {
    app: {
      test: 'test'
    },
  },
};

There is any solution to do that? I tried Object.assign but when I have 2 same named properties it just override them. So, when I have same lang in 2 object it should extend it, when I have different lang it should just add that to object. I cant use jquery or other lib, so it must be pure js (es6 avaible)

lukasz-p
  • 173
  • 1
  • 2
  • 13
  • https://davidwalsh.name/javascript-deep-merge – connexo Mar 15 '18 at 10:51
  • 1
    Possible duplicate of [How can I merge properties of two JavaScript objects dynamically?](https://stackoverflow.com/questions/171251/how-can-i-merge-properties-of-two-javascript-objects-dynamically) – str Mar 15 '18 at 10:51
  • https://github.com/KyleAMathews/deepmerge – connexo Mar 15 '18 at 10:52
  • @str nope, it's not duplicate, when I have same object property I need to extend them, not override – lukasz-p Mar 15 '18 at 10:59
  • @lukasz-p Yes it is a duplicate, just have a look at more than the first answer only. – str Mar 15 '18 at 11:00
  • There is no reliable and flexible deep merge code snippet which achieves what you need with like 2 or 3 lines of code. So either you code an inflexible, but short solution for your specific use-case, or you use a tiny library like the one mentioned. Ofc you are also free to write such a lib yourself. – connexo Mar 15 '18 at 11:52

1 Answers1

0

You can use a small library called deepmerge:

(function (global, factory) {typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.deepmerge = factory());}(this, (function () { 'use strict';var isMergeableObject = function isMergeableObject(value) {return isNonNullObject(value) && !isSpecial(value)};function isNonNullObject(value) {return !!value && typeof value === 'object'}function isSpecial(value) {var stringValue = Object.prototype.toString.call(value);return stringValue === '[object RegExp]' || stringValue === '[object Date]' || isReactElement(value)}/* see https://github.com/facebook/react/blob/b5ac963fb791d1298e7f396236383bc955f916c1/src/isomorphic/classic/element/ReactElement.js#L21-L25*/var canUseSymbol = typeof Symbol === 'function' && Symbol.for;var REACT_ELEMENT_TYPE = canUseSymbol ? Symbol.for('react.element') : 0xeac7;function isReactElement(value) {return value.$$typeof === REACT_ELEMENT_TYPE}function emptyTarget(val) {return Array.isArray(val) ? [] : {}}function cloneUnlessOtherwiseSpecified(value, options) {return (options.clone !== false && options.isMergeableObject(value)) ? deepmerge(emptyTarget(value), value, options) : value}function defaultArrayMerge(target, source, options) {return target.concat(source).map(function(element) {return cloneUnlessOtherwiseSpecified(element, options)})}function mergeObject(target, source, options) {var destination = {};if (options.isMergeableObject(target)) {Object.keys(target).forEach(function(key) {destination[key] = cloneUnlessOtherwiseSpecified(target[key], options);});}Object.keys(source).forEach(function(key) {if (!options.isMergeableObject(source[key]) || !target[key]) {destination[key] = cloneUnlessOtherwiseSpecified(source[key], options);} else {destination[key] = deepmerge(target[key], source[key], options);}});return destination}function deepmerge(target, source, options) {options = options || {};options.arrayMerge = options.arrayMerge || defaultArrayMerge;options.isMergeableObject = options.isMergeableObject || isMergeableObject;var sourceIsArray = Array.isArray(source);var targetIsArray = Array.isArray(target);var sourceAndTargetTypesMatch = sourceIsArray === targetIsArray;if (!sourceAndTargetTypesMatch) {return cloneUnlessOtherwiseSpecified(source, options)} else if (sourceIsArray) {return options.arrayMerge(target, source, options)} else {return mergeObject(target, source, options)}}deepmerge.all = function deepmergeAll(array, options) {if (!Array.isArray(array)) {throw new Error('first argument should be an array')}return array.reduce(function(prev, next) {return deepmerge(prev, next, options)}, {})};var deepmerge_1 = deepmerge;return deepmerge_1;

})));

const langs = {
  en: {
    components: {
      test: 'test'
    },
  },
  de: {
    components: {
      test: 'test'
    },
  },
};

const langs2 = {
  en: {
    app: {
      test: 'test'
    },
  },
  pl: {
    app: {
      test: 'test'
    },
  },
};

let result = deepmerge(langs, langs2);

console.log(result);

https://github.com/KyleAMathews/deepmerge

connexo
  • 53,704
  • 14
  • 91
  • 128