GithubHelp home page GithubHelp logo

deepmerge's Introduction

deepmerge

Merges the enumerable properties of two or more objects deeply.

UMD bundle is 723B minified+gzipped

Getting Started

Example Usage

const x = {
	foo: { bar: 3 },
	array: [{
		does: 'work',
		too: [ 1, 2, 3 ]
	}]
}

const y = {
	foo: { baz: 4 },
	quux: 5,
	array: [{
		does: 'work',
		too: [ 4, 5, 6 ]
	}, {
		really: 'yes'
	}]
}

const output = {
	foo: {
		bar: 3,
		baz: 4
	},
	array: [{
		does: 'work',
		too: [ 1, 2, 3 ]
	}, {
		does: 'work',
		too: [ 4, 5, 6 ]
	}, {
		really: 'yes'
	}],
	quux: 5
}

merge(x, y) // => output

Installation

With npm do:

npm install deepmerge

deepmerge can be used directly in the browser without the use of package managers/bundlers as well: UMD version from unpkg.com.

Include

deepmerge exposes a CommonJS entry point:

const merge = require('deepmerge')

The ESM entry point was dropped due to a Webpack bug.

API

merge(x, y, [options])

Merge two objects x and y deeply, returning a new merged object with the elements from both x and y.

If an element at the same key is present for both x and y, the value from y will appear in the result.

Merging creates a new object, so that neither x or y is modified.

Note: By default, arrays are merged by concatenating them.

merge.all(arrayOfObjects, [options])

Merges any number of objects into a single result object.

const foobar = { foo: { bar: 3 } }
const foobaz = { foo: { baz: 4 } }
const bar = { bar: 'yay!' }

merge.all([ foobar, foobaz, bar ]) // => { foo: { bar: 3, baz: 4 }, bar: 'yay!' }

Options

arrayMerge

There are multiple ways to merge two arrays, below are a few examples but you can also create your own custom function.

Your arrayMerge function will be called with three arguments: a target array, the source array, and an options object with these properties:

  • isMergeableObject(value)
  • cloneUnlessOtherwiseSpecified(value, options)

arrayMerge example: overwrite target array

Overwrites the existing array values completely rather than concatenating them:

const overwriteMerge = (destinationArray, sourceArray, options) => sourceArray

merge(
	[1, 2, 3],
	[3, 2, 1],
	{ arrayMerge: overwriteMerge }
) // => [3, 2, 1]

arrayMerge example: combine arrays

Combines objects at the same index in the two arrays.

This was the default array merging algorithm pre-version-2.0.0.

const combineMerge = (target, source, options) => {
	const destination = target.slice()

	source.forEach((item, index) => {
		if (typeof destination[index] === 'undefined') {
			destination[index] = options.cloneUnlessOtherwiseSpecified(item, options)
		} else if (options.isMergeableObject(item)) {
			destination[index] = merge(target[index], item, options)
		} else if (target.indexOf(item) === -1) {
			destination.push(item)
		}
	})
	return destination
}

merge(
	[{ a: true }],
	[{ b: true }, 'ah yup'],
	{ arrayMerge: combineMerge }
) // => [{ a: true, b: true }, 'ah yup']

isMergeableObject

By default, deepmerge clones every property from almost every kind of object.

You may not want this, if your objects are of special types, and you want to copy the whole object instead of just copying its properties.

You can accomplish this by passing in a function for the isMergeableObject option.

If you only want to clone properties of plain objects, and ignore all "special" kinds of instantiated objects, you probably want to drop in is-plain-object.

const { isPlainObject } = require('is-plain-object')

function SuperSpecial() {
	this.special = 'oh yeah man totally'
}

const instantiatedSpecialObject = new SuperSpecial()

const target = {
	someProperty: {
		cool: 'oh for sure'
	}
}

const source = {
	someProperty: instantiatedSpecialObject
}

const defaultOutput = merge(target, source)

defaultOutput.someProperty.cool // => 'oh for sure'
defaultOutput.someProperty.special // => 'oh yeah man totally'
defaultOutput.someProperty instanceof SuperSpecial // => false

const customMergeOutput = merge(target, source, {
	isMergeableObject: isPlainObject
})

customMergeOutput.someProperty.cool // => undefined
customMergeOutput.someProperty.special // => 'oh yeah man totally'
customMergeOutput.someProperty instanceof SuperSpecial // => true

customMerge

Specifies a function which can be used to override the default merge behavior for a property, based on the property name.

The customMerge function will be passed the key for each property, and should return the function which should be used to merge the values for that property.

It may also return undefined, in which case the default merge behaviour will be used.

const alex = {
	name: {
		first: 'Alex',
		last: 'Alexson'
	},
	pets: ['Cat', 'Parrot']
}

const tony = {
	name: {
		first: 'Tony',
		last: 'Tonison'
	},
	pets: ['Dog']
}

const mergeNames = (nameA, nameB) => `${nameA.first} and ${nameB.first}`

const options = {
	customMerge: (key) => {
		if (key === 'name') {
			return mergeNames
		}
	}
}

const result = merge(alex, tony, options)

result.name // => 'Alex and Tony'
result.pets // => ['Cat', 'Parrot', 'Dog']

clone

Deprecated.

Defaults to true.

If clone is false then child objects will be copied directly instead of being cloned. This was the default behavior before version 2.x.

Testing

With npm do:

npm test

License

MIT

deepmerge's People

Contributors

artskydj avatar bloomca avatar callumacrae avatar cfnelson avatar danielmschmidt avatar gagan-bansal avatar grifotv avatar kodypeterson avatar kyleamathews avatar lexi-lambda avatar macdja38 avatar mnespor avatar msssk avatar nataly87s avatar natesilva avatar nikolajdl avatar oscargodson avatar phanect avatar raddevon avatar rsolomo avatar simenb avatar smacpherson64 avatar tehshrike avatar teppeis avatar trysound avatar tuananh avatar wildlyinaccurate avatar williamboman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

deepmerge's Issues

Allow custom `isMergeableObject` functions

See #93 - a suggested implementation that is prompted by someone not wanting to copy moment objects directly instead of having their properties cloned.

Would solve #90 - allowing people to pass in their own whitelist-based functions.

Make sure to update the readme with examples that include an exception for moment, and replacing entirely with is-plain-object.

Not merging mongoose Models

I'd rather be using this lightweight library to handle deep merges instead of lodash. However after several attempts I'm unable to do a merge (even for a top level key) on a mongoose model object.

const merge = require('deepmerge');

var modelToUpdate = {"employees":[{"_id":"5a97e47097db2746fb986e8c","firstName":"John","lastName":"Doe","__v":0}],"_id":"5a98950568b7564cacc60c85","companyName":"Edit this top level","__v":0}

var updatePath = {companyName: "Not working"}

merge(modelToUpdate, updatePath)

// => {"employees":[{"_id":"5a97e47097db2746fb986e8c","firstName":"John","lastName":"Doe","__v":0}],"_id":"5a98950568b7564cacc60c85","companyName":"Edit this top level","__v":0}

If I try this with either Object.assign() or lodash.merge() I get the correct output:

 {"employees":[{"_id":"5a97e47097db2746fb986e8c","firstName":"John","lastName":"Doe","__v":0}],"_id":"5a98950568b7564cacc60c85","companyName":"Not working","__v":0}

I've json.stringified the results of the object being merged for clarity in this post.
Has anybody got any experience with handling Mongoose models?

Having trouble importing deepmerge with Webpack

When importing deepmerge with import * as merge from 'deepmerge'; throws Error: merge is not a function in the app, while the tests run just fine.

When importing with import merge from deepmerge;, the app works fine, but the jest tests throw TypeError: deepmerge_1.default is not a function`.

I have temporarily patched the issue in my code with an if/else block to reassign the correct function to the variable, but I feel there must be a better way.

Maybe jest is misconfigured. Has anyone ever encountered a similar issue or can provide a configuration template that is proven to be working?

This describes a similar issue to what I am experiencing aurelia/skeleton-navigation#606, though I am not using Aurelia, nor Moment. It just seems like the same kind of problem.


Node version: 8.6.0
NPM version: 5.5.1
Webpack version: 3.6.0
Typescript version: 2.5.3
deepmerge version: 2.0.1


tsconfig.json

{
  "compilerOptions": {
    "outDir": "./dist/",
    "sourceMap": true,
    "noImplicitAny": false,
    "module": "commonjs",
    "target": "es5",
    "lib": ["es7", "es2017", "dom"],
    "jsx": "preserve",
    "allowJs": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "**/*.test.ts"]
}

.babelrc

{
  "presets": ["env", "react"],
  "plugins": [
    "react-css-modules"
  ]
}

jest.config.json

{
  "transform": {
    ".(ts|tsx)": "<rootDir>/node_modules/ts-jest/preprocessor.js"
  },
  "testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$",
  "moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json"]
}

Issue merging arrays with target length < source length

Hello,

I am experiencing a strange issue merging arrays of different length. especially when first array length is lower than second

var target = ['one'];
var source = ['two','three'];

merge(target, source) ==> [ 'one', 'three' ]

I expected to found

[ 'one', 'two','three' ]

thx

Make a check for string first, overwrite strings.

I have an object with lots of props, some of them are objects, some string.
I am looping over each key to see if it already exists on another object.
if it does, i'm merging the value of those props.
however, this is sometimes not an object but a string!

With merge() if I try merge('ab', 'ba') I end up with an object: {0: 'b', 1: 'a'}.

Maybe deepmerge can first check if it's really an object, and if it's strings just return the last string?

my snippet:

return Object.keys(doc).forEach(key => {
          // Merge if exists
          const newVal = (state[key])
            ? merge(state[key], doc[key], {arrayMerge: overwriteMerge})
            : doc[key]
          this._vm.$set(state, key, newVal)
        })

Unable to install with bower

Hi,
I have an issue with the latest release (1.4.1), it looks like the module uses 'is-mergeable-object' which is missing...

jasmine-node is broken, can't run the tests

There's some upstream problem with jasmine-node's requirejs dependency.

substack : deepmerge $ npm install .
npm http GET https://registry.npmjs.org/jasmine-node
npm http 200 https://registry.npmjs.org/jasmine-node
npm http GET https://registry.npmjs.org/jasmine-node/-/jasmine-node-1.0.22.tgz
npm http 200 https://registry.npmjs.org/jasmine-node/-/jasmine-node-1.0.22.tgz
npm http GET https://registry.npmjs.org/jasmine-reporters
npm http GET https://registry.npmjs.org/requirejs
npm http GET https://registry.npmjs.org/underscore
npm http GET https://registry.npmjs.org/coffee-script
npm http GET https://registry.npmjs.org/findit
npm http 200 https://registry.npmjs.org/findit
npm http 408 https://registry.npmjs.org/requirejs
npm ERR! registry error parsing json
npm ERR! error installing [email protected]
npm http 408 https://registry.npmjs.org/jasmine-reporters
npm ERR! registry error parsing json
npm http 408 https://registry.npmjs.org/underscore
npm ERR! registry error parsing json

npm ERR! Error: failed to fetch from registry: requirejs
npm ERR!     at /home/substack/.nave/installed/0.6.11/lib/node_modules/npm/lib/utils/npm-registry-client/get.js:139:12
npm ERR!     at cb (/home/substack/.nave/installed/0.6.11/lib/node_modules/npm/lib/utils/npm-registry-client/request.js:32:9)
npm ERR!     at Request._callback (/home/substack/.nave/installed/0.6.11/lib/node_modules/npm/lib/utils/npm-registry-client/request.js:154:14)
npm ERR!     at Request.callback (/home/substack/.nave/installed/0.6.11/lib/node_modules/npm/node_modules/request/main.js:109:22)
npm ERR!     at Request.<anonymous> (/home/substack/.nave/installed/0.6.11/lib/node_modules/npm/node_modules/request/main.js:481:18)
npm ERR!     at Request.emit (events.js:67:17)
npm ERR!     at IncomingMessage.<anonymous> (/home/substack/.nave/installed/0.6.11/lib/node_modules/npm/node_modules/request/main.js:442:16)
npm ERR!     at IncomingMessage.emit (events.js:88:20)
npm ERR!     at HTTPParser.onMessageComplete (http.js:137:23)
npm ERR!     at CleartextStream.ondata (http.js:1150:24)
npm ERR! You may report this log at:
npm ERR!     <http://github.com/isaacs/npm/issues>
npm ERR! or email it to:
npm ERR!     <[email protected]>
npm ERR! 
npm ERR! System Linux 2.6.38-8-generic
npm ERR! command "node" "/home/substack/prefix/bin/npm" "install" "."
npm ERR! cwd /home/substack/projects/deepmerge
npm ERR! node -v v0.6.11
npm ERR! npm -v 1.1.1
npm ERR! message failed to fetch from registry: requirejs
npm http 408 https://registry.npmjs.org/coffee-script
npm ERR! registry error parsing json
npm ERR! 
npm ERR! Additional logging details can be found in:
npm ERR!     /home/substack/projects/deepmerge/npm-debug.log
npm not ok
substack : deepmerge $ 

Jasmine-node is terrible in other respects, like using globals instead of exports. Consider removing it.

Merging mangles objects like FormData and File

It seems like FormData and File are converted to empty objects in the resulting merged set.

import merge from 'deepmerge';
let defaults = {};
let incoming = { formData: new FormData() };
merge(defaults, incoming); // => { formData: {} }

Expose `cloneUnlessOtherwiseSpecified` to array merge function

As noted in #84, it's awkward that you have to manually require/depend on is-mergeable-object to use it in a custom array merging function.

Also, as you can see from the oldArrayMerge example, reimplementing the cloning logic clutters up the code a good bit.

If those functions were exposed to the custom array merging function (probably in the third-argument options object?), it would make implementing those functions a lot simpler.

Discussion point: what should the name of the clone function be when passed in? cloneUnlessOtherwiseSpecified is appropriate in the code, I think, should we keep that here?

Discussion/pull requests welcome.

Doesn't build in old versions of node

deepmerge itself should still work in pretty old versions of JavaScript, but rollup doesn't run in node 0.10 or 0.12, which we currently test on.

Should we drop automated testing on old node versions? Should we try to work around this somehow? I'd rather avoid committing dist files to the repo if possible, but if testing old node is still a priority, that's one way to work around this.

Arrays with similar items merge in an unexpected manner

Great library! I have a small issue with a certain behaviour though. Maybe it's on purpose.

var merge = require('../')
var x = { foo : { 'bar' : 3 }, ar : [ { thing : 'b' } ] }
var y = { foo : { 'baz' : 4 }, quux : 5, ar : [ { thing : 'a' } ] }
var merged = merge(x, y)
console.dir(merged)

I would expect merged to look like this:

{ foo: { bar: 3, baz: 4 }, ar: [ { thing : 'b' }, { thing: 'a' } ], quux: 5 }

However it looks like this:

{ foo: { bar: 3, baz: 4 }, ar: [ { thing: 'a' } ], quux: 5 }

To me the behaviour I expect makes more sense because an array is likely to be a set of similar objects with shared keys but different values for those keys. However, I understand if that is not one of the behaviours that you would expect with the library so I shall make my own fork, and if you agree with my expected behaviour, I'll do a pull request for it ๐Ÿ˜„

Who'd like to take over this module?

Hi folks, I don't use this module any more and am really busy with work / other open source work and this module deserves far better maintainership than I've been giving it.

I'm tagging everyone who's contributed to this module in the past or who has an open PR. I'm willing to give out push access to everyone interested and if one of you would like to take on chief maintenance responsibility for owning the repo + NPM, I'll hand those over to you.

The main work that needs done here is to pick a solution for the array merging issue and release a 1.0.

Thanks.

@nhocki @nrf110 @anthonator @JoeStanton @nileshchavan @kodypeterson @gilbertwat @vvo @gyzerok @vyorkin @substack @SimenB @OscarGodson @rsolomo @PhUU

import not work,when use rullup

when :use rullup==> umd/cjs/es
import deepmerge from "deepmerge" not work
import * as deepmerge from "deepmerge" not work
import { deepmerge } from "deepmerge" not work

bug this work:
import deepmerge_1 from "deepmerge"
๐Ÿ˜†

Allow the source object to be null or undefined

โžœ node
> let deepmerge = require('deepmerge');
undefined
> deepmerge({}, undefined)
TypeError: Cannot convert undefined or null to object

Could you provide the same behaviour like Object.assign?

Should we publish a version 2?

This module is pretty stable, but there are a few pieces of backwards-compatibility cruft that I would trim given the chance.

  1. The default array merging algorithm is complicated and I don't think anyone could guess what it was without reading the code
  2. By default, a new object is created for the output, but any child objects are moved right over instead of being cloned, unless you pass in clone: true

Since you can pass in custom array merge functions, I would rather default to the super-simple method of just concatenating arrays and let people do more complicated things on their own if they need to.

I think clone should default to true - I think it's what people would most likely expect, and it's the safer option.

We could even consider deprecating the clone option and eventually supporting only deep clones. This seems doable because nobody has apparently had any issue with the fact that a new object is always created for the output already.

If we always cloned, it would also free us up to make merge.all a bit more forgiving, ala #71.

So:

  • Is cleaning up this cruft worth publishing a breaking change?
  • Is there any other cruft you can think of that could be cleaned up in a breaking change?

loading with requirejs cause error

Trying to use html5-skin project (https://github.com/ooyala/html5-skin ) which has dependency of deepmerge.
When loading html5-skin via requirejs, it causes Mismatched anonymous define() module: function ()`
Is there anything i need to do to use this library via requirejs...
It works fine when loading wihtout requirejs..

Feature - Overlay option

I have a use case where I want to overlay one object on another instead of merging the 2 objects into a 3rd new object. I made a modification to deepmerge to accept an "overlay" option which will cause properties to be copied to the target object instead of creating a new destination object. After this change it satisfies my use case. Is this something that would be helpful to contribute to the project?

Add a object-key merge option

Hi,

deepmerge solves lots of my requirements, but the following is not possible right now:

var x = {
  foo__1: { bar: 3 },
}

var y = {
  foo__2: { baz: 4 },
}

var expected = {
  foo: {
    bar: 3,
    baz: 4
  },
}

merge(x, y) // => expected

I cannot change the shape of "x" and "y". The keys needs to be transformed before the actual merge process. In the example above the transformation would look like this:

(key) => key.split("__")[0]

This could be implemented as an option. Similar to "arrayMerge", but for objects.

I do not see any simple way to implement this requirement outside of the deepmerge.

How do you think about this?

If you consider this a useful feature, then I will try to implement it as a PR.

Limitation? complete deep merge

Hi, I think I found a limitation.
Could you please implement a fix?

const merge = require('deepmerge');
test('merge full arrays', function(t) {
	let a = {
		'row': [
			{ 'a': { 'x': 1 } },
			{ 'b': { 'y': 1 } },
			{ 'c': { 'z': 1 } }
		] };
	let b = {
		'row': [
			{ 'a': { 'm': 2 } },
			{ 'b': { 'n': 2 } },
			{ 'c': { 'o': 2 } }
		] };
	let expected = {
		'row': [
			{ 'a': { 'x': 1, 'm': 2 } },
			{ 'b': { 'y': 1, 'n': 2 } },
			{ 'c': { 'z': 1, 'o': 2 } }
		] };
	var actual = merge(a,b)
	t.deepEqual(actual, expected)
	t.end()
})

I would like to help more, but I'm kind of dumb and I do not know how to solve.

Why removing Bower ?

Can you tell us why you removed the Bower file ? Luckily the package is still instable but as there is not more bower.json with the "main" definition, built tools cannot automatically inject the plugin without extra config.

Not everyone is using Webpack or such npm based tools.

merging shorter and longer array

if you merge target = [0,1,2] and src = [0,1,2,3], the merge is called recursively with target[3] and thus giving an error on line 28. This code should fix this issue (on line 8):

    src.forEach(function(e, i) {
        if(typeof target[i] == 'undefined'){
            dst[i] = e;
        }else if (typeof e === 'object') {
            dst[i] = merge(target[i], e)
        } else {
            if (target.indexOf(e) === -1) {
                dst.push(e)
            }
        }
    })

Dates should merge

For example:

$ node
> require('deepmerge')({a:new Date()}, {a:new Date()})
{ a: {} }

Expected behavior:

$ node
> require('deepmerge')({a:new Date()}, {a:new Date()})
{ a: Mon Apr 11 2016 19:25:29 GMT-0400 (EDT) }

Merging [ ] into empty { } throws an exception

var a = { foo: {} }
var b = { foo: [] }
merge(a, b)

throws...

/node_modules/deepmerge/index.js:18
src.forEach(function(e, i) {
    ^
TypeError: target.indexOf is not a function

My guess is because the iterator sees that b.foo is array and then tries to read indexOf object type. Not sure what the right behavior is, just thought I'd report it.

Add "clone" option

here is the test

var src = {
  "b": {
    "c": 'foo'
  }
}

var target = {
  "a": {}
}

var expected = {
  "a": {},
  "b": {
    "c": 'foo'
  }
}
var combined = merge(target, src)
src.b.c = 'bar'

console.log(combined.b.c)
// output as
// 'bar'
// though it should be 'foo'

Is this intentional behavior? I think in most of the cases source object should be cloned.

Regular expressions not merged

Apologies if this is expected behavior but I am not seeing regular expressions come through merges.
Seeing the following behavior in 0.2.10 fresh install from npm

var deepmerge = require('deepmerge');

var obj1 = {
  test: /\.js?$/,
}

var obj2 = {
  test: /\.jsx?$/,
}

console.log(obj1.test.test('file.js'));
console.log(obj2.test.test('file.jsx'));

var result = deepmerge(obj1, obj2);

console.log(result.test.test('file.js'));
console.log(result.test.test('file.jsx'));
$ node deepmergetest.js 
true
true
/home/danny/bm/pub/scratch/deepmergetest.js:18
console.log(result.test.test('file.js'));
                        ^
TypeError: undefined is not a function
    at Object.<anonymous> (/home/danny/bm/pub/scratch/deepmergetest.js:18:25)
    at Module._compile (module.js:460:26)
    at Object.Module._extensions..js (module.js:478:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Function.Module.runMain (module.js:501:10)
    at startup (node.js:129:16)
    at node.js:814:3

merge.all with single element array

I'm curious why when one calls merge.all() with a single element array, [{'a':1}], this function doesnt just return the value of that first element in the array {'a':1}? The function is instead throwing an error.

In my code, I'm dynamically creating an array of objects that I need to merge together. Occasionally, that array only has one element. To protect against this error I have to add .concat({}) to the array argument increase its length to 2.

merge {a: {}}, {b: c: {}}

Trying to merge({"a": {}}, {"b": {"c": {}}}) I get:

TypeError: Cannot read property 'c' of undefined
    at /Users/om/Git/a/dm/node_modules/deepmerge/index.js:29:40
    at Array.forEach (native)
    at merge (/Users/om/Git/a/dm/node_modules/deepmerge/index.js:24:26)
    at /Users/om/Git/a/dm/node_modules/deepmerge/index.js:29:28
    at Array.forEach (native)
    at merge (/Users/om/Git/a/dm/node_modules/deepmerge/index.js:24:26)
    at Object.<anonymous> (/Users/om/Git/a/dm/issue.coffee:8:15)
    at Object.<anonymous> (/Users/om/Git/a/dm/issue.coffee:16:4)
    at Module._compile (module.js:446:26)
    at Object.run (/Users/om/A/pkg/lib/node_modules/coffee-script/lib/coffee-script/coffee-script.js:68:25)

If "b": {} is present in the first object, all is ok.

Array to Object not working as expected

Having some problems with converting arrays to objects and discarding current array values.

const deepmerge = require('deepmerge');

const x = {
  prop: ['hello'],
}

const y = {
  prop: {
    name: 'foo',
    value: 'bar'
  }
}

const result = deepmerge(x, y);

result.prop 
// expected { name: 'foo', value: 'bar' } but resulted in { 0: 'hello', name: 'foo', value: 'bar' }  

Is it possible to achieve what I'm looking for?

License

Can you please include a license.

merge with empty object

Hello,i have issue with merging. I dont even know how you could help, but still.

let item = {key: {innerKey: "value"}}
let item2 = {key: {}}
deepmerge(item, item2) // {key: {innerKey: "value"}}

is there some workaround?

Ability to set default options

Would you be open for a PR where we can specify the default options globally?

My arrayMerge strategy is to always overwrite the array instead of concatenating, so it's quite annoying to have to specify the options with the overwrite function every time I use deepmerge across various files, and it has already caused some annoying bugs.

Example:

const merge = require('deepmerge');
merge.setDefaultOptions({
  arrayMerge: (dest, source) => source,
});

Afterwards, every merge would use those options as the default, unless specific options are passed in.
Happy to create a PR for it.

Is it possible to opt-out of array merging?

It's a really nice feature, but sometimes it's not the right thing.

Or is there a quick fix how to prevent the merging of all array items, but rather replace the array with the one provided as the second argument?

Array's Concatenating instead of Merging

I originally installed this thinking that I could deep merge two objects, however it's concatenating array's rather than checking to see if it already exists and merging them.

default = {
    scales: {
        xAxes: [{
            display: false
        }]
    }
}

override = {
    scales: {
        xAxes: [{
            display: true
        }]
    }
}

let combined = merge(default, override);

// expected results
combined.scales.xAxes == [{ display: true }]

// actual results
combined.scales.xAxes == [
    { display: false },
    { display: true }
]

Bump to 1.0?

Looks like the library's API is pretty stable (once #12 and #14 are closed).

oldArrayMerge() example code is non-executable

I'm trying to use the example oldArrayMerge() code given in the README but it won't run, as cloneIfNecessary() and isMergeableObject() are not defined. I see that isMergeableObject() can be got from another package (though it would be much neater if deepmerge could expose it as a pass-through), but cloneIfNecessary() doesn't seem to be defined anywhere.

My code depends on the pre-2.0.0 behaviour for array merging, so it would be really helpful to be able to reproduce this on the latest 2.0.0 code.

Thanks for this tool; it is very helpful, and I also appreciate the efforts you have gone to to explain how to keep the pre-2.0.0 behaviour; hope this issue report helps with that.

Return first object if nothing is changed?

I'm looking for this behaviour:

var x = { foo: { bar: 3 }, baz: 4 };
var y = { foo: { bar: 5 } };
var z = { foo: { bar: 3 } };

var result1 = merge(x, y);
var result2 = merge(x, z);

assert(result1 === x) // => false
assert(result2 === x) // => true

Currently a new object is always created so this does not hold. Not sure if this is an unreasonable request or out of scope, I've had a look at Lodash and Ramda but can't seem to find this anywhere.

Merge.all not honoring options to not merge arrays

`import merge from "deepmerge";

const orig = {
errorMessage: {
description: ["Hello array world!"]
}
};

const replacement = {
errorMessage: {
description: []
}
};

const dontMerge = (destination, source) => source;

it("merges arrays correctly", () => {
const result = merge.all([orig, replacement], dontMerge);
expect(result.errorMessage.description.length).toEqual(0);
});
`

Unhandled JS Exception when one of the item in object is a React-Native element

I have 2 objects I'd like to deep merge. One element in the object is a React-Native element.

First object:

const obj1 = {
  headerStyle: {
    color: 'blue',
  },
  headerLeft: (
    <Text>Back</Text>
  )
};

const obj2 = {
  headerStyle: {
    backgroundColor: 'red',
  },
  headerLeft: (
    <Text>Close</Text>
  )
}

merge(obj1, obj2);

I get the following error when I try to merge those 2 objects:

Unhandled JS Exception: Maximum call stack size exceeded

screen shot 2017-09-19 at 16 12 09

Why would deepmerge assign 'undefined' attributes?

Currently deepmerge overwrites non-void attribute with undefined attribute:

$ node
const merge = require('./node_modules/deepmerge')
merge({ a: 'a' }, { a: undefined })
# Result: { a: undefined }

Why is this a desired behaviour?

IMHO, the conventional merge method should skip undefined value. The popular libarary Lodash also aggrees that rule, see http://stackoverflow.com/a/33247597/1401634.

Would you please at least provide an option to turn this behaviour off?

Cheers

[Webpack] Uncaught TypeError: deepmerge is not a function

Hi,

I've been using deepmerge in many of my libraries, mostly private but a few of my public ones as well. The most popular library of mine to use it, webdav, was recently updated to use deepmerge 2 - the import of deepmerge broke:

Uncaught TypeError: deepmerge is not a function
    at Object.getDirectoryContents (factory.js:118)
    at eval (main_init.js:86)

This has only occurred for me in the 2.* releases. I use commonjs to import deepmerge. The library is basic Javascript compatible with NodeJS 4 and upwards. I've tested that this breaks in a couple of webpack configurations.

EDIT: I've created a reproduction.

Unexpected behavior

deepmerge.all([{ a: 1 }, { a: 2 }], { isMergeableObject: (val) => { return val !== 1; } });
// expected: { a: 1 }
// actual: { a: {} }

Passing arguments by reference

Actual

options = deepmerge(options, { y: true });
options // {y: true}

Real example

module.exports = (options = {}) => {
	options = deepmerge({
		cache: true,
		format: 'node_modules/eslint-friendly-formatter',
		fix: true,
		extensions: ['.js']
	}, options);

options, options, options, so ugly ))

Expected

deepmerge(options, { y: true }, { reference: true });
options // {y: true}

It's just a proposal

Default option for arrayOverwrite

The current method to overwrite arrays is:

const overwriteMerge = (destinationArray, sourceArray, options) => sourceArray
merge(
	{a: [1, 2, 3]},
	{a: [3, 2, 1]},
	{ arrayMerge: overwriteMerge }
)

Everywhere I want to use this overwrite array option (which is a lot of places) I would have to define overwriteMerge or import it...

I would love standard compatibility with a syntax similar to:

merge(
	{a: [1, 2, 3]},
	{a: [3, 2, 1]}
	{ arrayMerge: 'overwrite' }
)

Just a humble request.
Best regards!

Does `clone: false` need to be deprecated?

I noticed that cloning a javascript class using the default deepmerge converts that class to a regular object, thereby loosing its functionality. Merging it with {clone: false} keeps the class, and thus its functionality, intact.

Therefor my question: will the {clone: false} option really be deprecated?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.