diff --git a/API.md b/API.md
index 62582f782..1fd4e6213 100644
--- a/API.md
+++ b/API.md
@@ -220,7 +220,7 @@ Insert API responses and lifecycle data into Onyx
| Param | Type | Description |
| --- | --- | --- |
-| data | Array | An array of objects with shape {onyxMethod: oneOf('set', 'merge'), key: string, value: *} |
+| data | Array | An array of objects with shape {onyxMethod: oneOf('set', 'merge', 'mergeCollection'), key: string, value: *} |
diff --git a/lib/Onyx.js b/lib/Onyx.js
index 1ed4db16e..1720367c0 100644
--- a/lib/Onyx.js
+++ b/lib/Onyx.js
@@ -812,12 +812,12 @@ function mergeCollection(collectionKey, collection) {
/**
* Insert API responses and lifecycle data into Onyx
*
- * @param {Array} data An array of objects with shape {onyxMethod: oneOf('set', 'merge'), key: string, value: *}
+ * @param {Array} data An array of objects with shape {onyxMethod: oneOf('set', 'merge', 'mergeCollection'), key: string, value: *}
*/
function update(data) {
// First, validate the Onyx object is in the format we expect
_.each(data, ({onyxMethod, key}) => {
- if (!_.contains(['set', 'merge'], onyxMethod)) {
+ if (!_.contains(['set', 'merge', 'mergeCollection'], onyxMethod)) {
throw new Error(`Invalid onyxMethod ${onyxMethod} in Onyx update.`);
}
if (!_.isString(key)) {
@@ -833,6 +833,9 @@ function update(data) {
case 'merge':
merge(key, value);
break;
+ case 'mergeCollection':
+ mergeCollection(key, value);
+ break;
default:
break;
}
diff --git a/tests/unit/onyxTest.js b/tests/unit/onyxTest.js
index 670dafe95..48772a81f 100644
--- a/tests/unit/onyxTest.js
+++ b/tests/unit/onyxTest.js
@@ -358,6 +358,89 @@ describe('Onyx', () => {
});
});
+ it('should use update data object to merge a collection of keys', () => {
+ const valuesReceived = {};
+ const mockCallback = jest.fn(data => valuesReceived[data.ID] = data.value);
+ connectionID = Onyx.connect({
+ key: ONYX_KEYS.COLLECTION.TEST_KEY,
+ initWithStoredValues: false,
+ callback: mockCallback,
+ });
+
+ return waitForPromisesToResolve()
+ .then(() => {
+ // GIVEN the initial Onyx state: {test_1: {existingData: 'test',}, test_2: {existingData: 'test',}}
+ Onyx.multiSet({
+ test_1: {
+ existingData: 'test',
+ },
+ test_2: {
+ existingData: 'test',
+ },
+ });
+ return waitForPromisesToResolve();
+ })
+ .then(() => {
+ expect(mockCallback.mock.calls[0][0]).toEqual({existingData: 'test'});
+ expect(mockCallback.mock.calls[0][1]).toEqual('test_1');
+
+ expect(mockCallback.mock.calls[1][0]).toEqual({existingData: 'test'});
+ expect(mockCallback.mock.calls[1][1]).toEqual('test_2');
+
+ // WHEN we pass a mergeCollection data object to Onyx.update
+ Onyx.update([
+ {
+ onyxMethod: 'mergeCollection',
+ key: ONYX_KEYS.COLLECTION.TEST_KEY,
+ value: {
+ test_1: {
+ ID: 123,
+ value: 'one',
+ },
+ test_2: {
+ ID: 234,
+ value: 'two',
+ },
+ test_3: {
+ ID: 345,
+ value: 'three',
+ },
+ },
+ },
+ ]);
+ return waitForPromisesToResolve();
+ })
+ .then(() => {
+ /* THEN the final Onyx state should be:
+ {
+ test_1: {
+ existingData: 'test'
+ ID: 123,
+ value: 'one',
+ },
+ test_2: {
+ existingData: 'test'
+ ID: 234,
+ value: 'two',
+ },
+ test_3: {
+ ID: 345,
+ value: 'three',
+ },
+ }
+ */
+
+ expect(mockCallback.mock.calls[2][0]).toEqual({ID: 123, value: 'one', existingData: 'test'});
+ expect(mockCallback.mock.calls[2][1]).toEqual('test_1');
+
+ expect(mockCallback.mock.calls[3][0]).toEqual({ID: 234, value: 'two', existingData: 'test'});
+ expect(mockCallback.mock.calls[3][1]).toEqual('test_2');
+
+ expect(mockCallback.mock.calls[4][0]).toEqual({ID: 345, value: 'three'});
+ expect(mockCallback.mock.calls[4][1]).toEqual('test_3');
+ });
+ });
+
it('should throw an error when the data object is incorrect in Onyx.update', () => {
// GIVEN the invalid data object with onyxMethod='multiSet'
const data = [