diff --git a/packages/toolkit/src/entities/sorted_state_adapter.ts b/packages/toolkit/src/entities/sorted_state_adapter.ts index 7731bd5ba7..c96f16380e 100644 --- a/packages/toolkit/src/entities/sorted_state_adapter.ts +++ b/packages/toolkit/src/entities/sorted_state_adapter.ts @@ -70,9 +70,14 @@ export function createSortedStateAdapter( newEntities = ensureEntitiesArray(newEntities) const existingKeys = new Set(existingIds ?? getCurrent(state.ids)) - + const addedKeys = new Set(); const models = newEntities.filter( - (model) => !existingKeys.has(selectIdValue(model, selectId)), + (model) => { + const modelId = selectIdValue(model, selectId); + const notAdded = !addedKeys.has(modelId); + if (notAdded) addedKeys.add(modelId); + return !existingKeys.has(modelId) && notAdded; + } ) if (models.length !== 0) { diff --git a/packages/toolkit/src/entities/tests/sorted_state_adapter.test.ts b/packages/toolkit/src/entities/tests/sorted_state_adapter.test.ts index d378449886..81ff44c409 100644 --- a/packages/toolkit/src/entities/tests/sorted_state_adapter.test.ts +++ b/packages/toolkit/src/entities/tests/sorted_state_adapter.test.ts @@ -588,6 +588,25 @@ describe('Sorted State Adapter', () => { }) }) + it('should work consistent with Unsorted State Adapter adding duplicate ids', () => { + const unsortedAdaptor = createEntityAdapter({ + selectId: (book: BookModel) => book.id + }); + + const firstEntry = {id: AClockworkOrange.id, author: TheHobbit.author } + const secondEntry = {id: AClockworkOrange.id, title: 'Zack' } + const withNothingSorted = adapter.setAll(state, []); + const withNothingUnsorted = unsortedAdaptor.setAll(state, []); + const withOneSorted = adapter.addMany(withNothingSorted, [ + { ...AClockworkOrange, ...firstEntry }, {...AClockworkOrange, ...secondEntry} + ]) + const withOneUnsorted = adapter.addMany(withNothingUnsorted, [ + { ...AClockworkOrange, ...firstEntry }, {...AClockworkOrange, ...secondEntry} + ]) + + expect(withOneSorted).toEqual(withOneUnsorted); + }) + it('should let you set many entities in the state when passing in a dictionary', () => { const changeWithoutAuthor = { id: TheHobbit.id, title: 'Silmarillion' } const withMany = adapter.setAll(state, [TheHobbit]) diff --git a/packages/toolkit/src/entities/tests/unsorted_state_adapter.test.ts b/packages/toolkit/src/entities/tests/unsorted_state_adapter.test.ts index d7b551e63b..6249f5706d 100644 --- a/packages/toolkit/src/entities/tests/unsorted_state_adapter.test.ts +++ b/packages/toolkit/src/entities/tests/unsorted_state_adapter.test.ts @@ -89,6 +89,26 @@ describe('Unsorted State Adapter', () => { }) }) + it('should let you add the only first occurrence for duplicate ids', () => { + const firstEntry = {id: AClockworkOrange.id, author: TheHobbit.author } + const secondEntry = {id: AClockworkOrange.id, title: 'Zack' } + const withOne = adapter.setAll(state, [TheGreatGatsby]) + const withMany = adapter.addMany(withOne, [ + { ...AClockworkOrange, ...firstEntry }, {...AClockworkOrange, ...secondEntry} + ]) + + expect(withMany).toEqual({ + ids: [TheGreatGatsby.id, AClockworkOrange.id], + entities: { + [TheGreatGatsby.id]: TheGreatGatsby, + [AClockworkOrange.id]: { + ...AClockworkOrange, + ...firstEntry, + }, + }, + }) + }) + it('should remove existing and add new ones on setAll', () => { const withOneEntity = adapter.addOne(state, TheGreatGatsby)