Search code examples
reactjsredux-toolkitrtk-queryimmer.js

Why is updateQueryData from RTK query not updating my state?


I'm using RTK query and I want to overwrite the state with the result from my transform request. I get my overview of a todos array by calling the getTodosOverview Query. After that I call a updateTodos query and this gives me back a new array with todos. I want to overwrite the original array with these results. I'm using the function updateQueryData but it doesnt seem to work. What am I missing here?

export const todosApi = createApi({
    reducerPath: 'todosApi',
    baseQuery: fetchBaseQuery({ baseUrl: 'api/todos' }),
    endpoints: (builder) => ({
      getToDosOverview: builder.query<Array<ToDos>, string>({
        query: () => `getOverview`,
        transformResponse: (rawResult: { data: Array<ToDos> }) => rawResult.data,
        keepUnusedDataFor: 0,
      }),
      updateTodos: builder.mutation<Array<ToDos>, string>({
        query: (fileId) => ({
          url: `updateTodos?fileId=${fileId}`,
          method: 'POST',
        }),
        transformResponse: (rawResult: { data: Array<ToDos> }) => rawResult.data,
        async onQueryStarted(uniqueIdentifier, { dispatch, queryFulfilled }) {
          const { data }= await queryFulfilled;
          // Update state with new data from response
          const patchResult = dispatch(
            todosApi.util.updateQueryData(
              'getToDosOverview',
              uniqueIdentifier,
              () => {
                return data;
              }
            )
          );
        },
      }),
    }),
  });

Solution

  • Well, you're not returning anything new.

              const patchResult = dispatch(
                todosApi.util.updateQueryData(
                  'getToDosOverview',
                  uniqueIdentifier,
                  // here you are getting the old state as a variable called `ToDos`
                  (ToDos: Array<ToDos>) => {
                    // and here you return that old state without any change
                    return ToDos;
                  }
                )
              );
    

    Also, you are doing that way before you have even received a response.

    The response will be available after the line

    await queryFulfilled;
    

    so you probably want to do something like

    const { data } = await queryFulfilled
    

    and then use data as the new value.

    Generally, it seems like you are copy-pasting from the "optimistic updates" example. Please look at the example of pessimistic updates instead.

    Also, with your code you are using the wrong argument if you want to update useGetToDosOverviewQuery(). You are updating useGetToDosOverviewQuery(uniqueIdentifier) here.

    You should probably call

    todosApi.util.updateQueryData('getToDosOverview', undefined, ...)