Skip to content

Commit 98e4511

Browse files
committed
Allow MERGE operations into empty array values
1 parent 434871e commit 98e4511

File tree

3 files changed

+49
-1
lines changed

3 files changed

+49
-1
lines changed

lib/OnyxUtils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1060,7 +1060,7 @@ function mergeInternal<TValue extends OnyxInput<OnyxKey> | undefined, TChange ex
10601060
return modifiedData;
10611061
},
10621062
{
1063-
result: (existingValue ?? {}) as TChange,
1063+
result: ((Array.isArray(existingValue) && existingValue.length === 0 ? {} : existingValue) ?? {}) as TChange,
10641064
replaceNullPatches: [],
10651065
},
10661066
);

lib/utils.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,12 @@ function checkCompatibilityWithExistingValue(value: unknown, existingValue: unkn
213213
isCompatible: true,
214214
};
215215
}
216+
// Empty arrays are compatible with objects — PHP's json_encode produces []
217+
// for empty associative arrays that should be {}.
218+
if (Array.isArray(existingValue) && existingValue.length === 0 && !Array.isArray(value)) {
219+
return {isCompatible: true};
220+
}
221+
216222
const existingValueType = Array.isArray(existingValue) ? 'array' : 'non-array';
217223
const newValueType = Array.isArray(value) ? 'array' : 'non-array';
218224
if (existingValueType !== newValueType) {

tests/unit/onyxTest.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,48 @@ describe('Onyx', () => {
182182
});
183183
});
184184

185+
it('should merge an object into an empty array (treating [] as {})', () => {
186+
let testKeyValue: unknown;
187+
188+
connection = Onyx.connect({
189+
key: ONYX_KEYS.TEST_KEY,
190+
initWithStoredValues: false,
191+
callback: (value) => {
192+
testKeyValue = value;
193+
},
194+
});
195+
196+
return Onyx.set(ONYX_KEYS.TEST_KEY, [])
197+
.then(() => {
198+
expect(testKeyValue).toStrictEqual([]);
199+
return Onyx.merge(ONYX_KEYS.TEST_KEY, {test: 'value'});
200+
})
201+
.then(() => {
202+
expect(testKeyValue).toStrictEqual({test: 'value'});
203+
});
204+
});
205+
206+
it('should still reject merging an object into a non-empty array', () => {
207+
let testKeyValue: unknown;
208+
209+
connection = Onyx.connect({
210+
key: ONYX_KEYS.TEST_KEY,
211+
initWithStoredValues: false,
212+
callback: (value) => {
213+
testKeyValue = value;
214+
},
215+
});
216+
217+
return Onyx.merge(ONYX_KEYS.TEST_KEY, ['existing'])
218+
.then(() => {
219+
expect(testKeyValue).toStrictEqual(['existing']);
220+
return Onyx.merge(ONYX_KEYS.TEST_KEY, {test: 'value'});
221+
})
222+
.then(() => {
223+
expect(testKeyValue).toStrictEqual(['existing']);
224+
});
225+
});
226+
185227
it('should notify subscribers when data has been cleared', () => {
186228
let testKeyValue: unknown;
187229
connection = Onyx.connect({

0 commit comments

Comments
 (0)