redux-toolkit: Optimistic updates not working on a graphql-based base query
I’m trying to implement optimistic updates on my graphql-based base query setup; however, after the mutation is triggered, the api.util.updateQueryData
call seems not to be updating the cached data.
Here’s my endpoint:
import { createApi, retry } from '@reduxjs/toolkit/query/react';
import { gql } from 'graphql-request';
import { graphqlRequestBaseQuery } from '@rtk-query/graphql-request-base-query';
export const api = createApi({
reducerPath: 'api',
baseQuery: backedOffGraphqlBaseQuery,
tagTypes: ['order', 'user', 'vehicle'],
endpoints: (builder) => ({
[...]
transitionOrderStatus: builder.mutation<string, { status: OrderStatus; orderId: string }>({
query: ({ status, orderId }) => ({
document: gql`mutation transitionOrderStatus($status: OrderStatus!, $orderId: String!) {
transitionOrderStatus(status: $status, orderId: $orderId)
}`,
variables: {
status,
orderId,
},
}),
async onQueryStarted({ orderId }, { dispatch, queryFulfilled }) {
const patchResult = dispatch(
api.util.updateQueryData('getOpenOrders', orderId, (ordersDraft) => {
const orders = ordersDraft.filter((o) => o.id !== orderId);
ordersDraft = orders;
}),
);
try {
await queryFulfilled;
} catch (error) {
patchResult.undo();
}
},
// invalidatesTags: ['order'],
}),
[...]
Any thoughts on why the dispatched api.util.updateQueryData
action is not getting the cached data updated?
Thanks! By the way, I’m almost done migrating our production web app to RTK Query and I’m fascinated by it. Also, I’ve found the docs extremely educative and just FUN!
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 21 (16 by maintainers)
Yes, it has to match exactly. Ultimately, the reducer logic is doing something like
state.api.queries[queryName + serializedQueryKey]
to determine which data should be updated. You must provided the exact same cache key in order for it to find that cached value.Just to add that bit of information:
getState
here cannot automatically have the right state type, as the api slice being created here would be a prerequisite to know that type - so the TS type here only contains the slice itself to not create a circular type reference. You would need to manually cast that to the correct type, as Mark already mentioned, by doingI’m not sure where exactly that pointer to
getState
gets its state type from.Worst case, you can
import type { RootState } from 'app/store'
to have the type accessible in this file, then do:assuming you’ve followed our standard TS setup guidelines:
https://redux.js.org/tutorials/typescript-quick-start
Your “slices” are adjacent to
state.api
, not inside of it. TrygetState().otherSliceHere
, etc.