Skip to content

Commit a04f8e9

Browse files
authored
Fix merging array-like objects (#659)
* test case * fix merging array-like object * Delete pnpm-lock.yaml * import array utils from validated-changeset * sync lock file
1 parent 92e790b commit a04f8e9

File tree

4 files changed

+2602
-3897
lines changed

4 files changed

+2602
-3897
lines changed

addon/utils/merge-deep.js

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
import { isChange, getChangeValue, normalizeObject } from 'validated-changeset';
1+
import {
2+
isChange,
3+
getChangeValue,
4+
normalizeObject,
5+
isArrayObject,
6+
objectToArray,
7+
arrayToObject,
8+
} from 'validated-changeset';
29

310
function isMergeableObject(value) {
411
return isNonNullObject(value) && !isSpecial(value);
@@ -146,17 +153,32 @@ export default function mergeDeep(target, source, options = {}) {
146153
let sourceAndTargetTypesMatch = sourceIsArray === targetIsArray;
147154

148155
if (!sourceAndTargetTypesMatch) {
156+
let sourceIsArrayLike = isArrayObject(source);
157+
158+
if (targetIsArray && sourceIsArrayLike) {
159+
return objectToArray(mergeTargetAndSource(arrayToObject(target), source, options));
160+
}
161+
149162
return source;
150163
} else if (sourceIsArray) {
151164
return source;
152-
}
153-
154-
try {
155-
return mergeTargetAndSource(target, source, options);
156-
} catch (e) {
157-
// this is very unlikely to be hit but lets throw an error otherwise
158-
throw new Error(
159-
'Unable to `mergeDeep` with your data. Are you trying to merge two ember-data objects? Please file an issue with ember-changeset.'
160-
);
165+
} else if (target === null || target === undefined) {
166+
/**
167+
* If the target was set to null or undefined, we always want to return the source.
168+
* There is nothing to merge.
169+
*
170+
* Without this explicit check, typeof null === typeof {any object-like thing}
171+
* which means that mergeTargetAndSource will be called, and you can't merge with null
172+
*/
173+
return source;
174+
} else {
175+
try {
176+
return mergeTargetAndSource(target, source, options);
177+
} catch (e) {
178+
// this is very unlikely to be hit but lets throw an error otherwise
179+
throw new Error(
180+
'Unable to `mergeDeep` with your data. Are you trying to merge two ember-data objects? Please file an issue with ember-changeset.'
181+
);
182+
}
161183
}
162184
}

0 commit comments

Comments
 (0)