Skip to content

Commit 29f4e4f

Browse files
authored
Merge pull request #2669 from reduxjs/fix-upsert
2 parents d9e481b + 1b631d3 commit 29f4e4f

File tree

2 files changed

+38
-2
lines changed

2 files changed

+38
-2
lines changed

packages/toolkit/src/query/core/buildSlice.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,8 @@ export function buildSlice({
136136
extraReducers(builder) {
137137
builder
138138
.addCase(queryThunk.pending, (draft, { meta, meta: { arg } }) => {
139-
if (arg.subscribe) {
139+
const upserting = isUpsertQuery(arg)
140+
if (arg.subscribe || upserting) {
140141
// only initialize substate if we want to subscribe to it
141142
draft[arg.queryCacheKey] ??= {
142143
status: QueryStatus.uninitialized,
@@ -148,7 +149,7 @@ export function buildSlice({
148149
substate.status = QueryStatus.pending
149150

150151
substate.requestId =
151-
isUpsertQuery(arg) && substate.requestId
152+
upserting && substate.requestId
152153
? // for `upsertQuery` **updates**, keep the current `requestId`
153154
substate.requestId
154155
: // for normal queries or `upsertQuery` **inserts** always update the `requestId`

packages/toolkit/src/query/tests/optimisticUpserts.test.tsx

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,41 @@ describe('basic lifecycle', () => {
9898
onSuccess.mockReset()
9999
})
100100

101+
test('Does basic inserts and upserts', async () => {
102+
const newPost: Post = {
103+
id: '3',
104+
contents: 'Inserted content',
105+
title: 'Inserted title',
106+
}
107+
const insertPromise = storeRef.store.dispatch(
108+
api.util.upsertQueryData('post', newPost.id, newPost)
109+
)
110+
111+
await insertPromise
112+
113+
const selectPost3 = api.endpoints.post.select(newPost.id)
114+
const insertedPostEntry = selectPost3(storeRef.store.getState())
115+
expect(insertedPostEntry.isSuccess).toBe(true)
116+
expect(insertedPostEntry.data).toEqual(newPost)
117+
118+
const updatedPost: Post = {
119+
id: '3',
120+
contents: 'Updated content',
121+
title: 'Updated title',
122+
}
123+
124+
const updatePromise = storeRef.store.dispatch(
125+
api.util.upsertQueryData('post', updatedPost.id, updatedPost)
126+
)
127+
128+
await updatePromise
129+
130+
const updatedPostEntry = selectPost3(storeRef.store.getState())
131+
132+
expect(updatedPostEntry.isSuccess).toBe(true)
133+
expect(updatedPostEntry.data).toEqual(updatedPost)
134+
})
135+
101136
test('success', async () => {
102137
const { result } = renderHook(
103138
() => extendedApi.endpoints.test.useMutation(),

0 commit comments

Comments
 (0)