Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RTK-Query updateQueryData callback is not called #2247

Closed
WingsDevelopment opened this issue Apr 16, 2022 · 13 comments
Closed

RTK-Query updateQueryData callback is not called #2247

WingsDevelopment opened this issue Apr 16, 2022 · 13 comments

Comments

@WingsDevelopment
Copy link

WingsDevelopment commented Apr 16, 2022

I am trying to manually add query data cache for each item in list, after loading whole list.
It's simple table view, after which I would like to have instant load on each details view for any of the items in the list.. And I can't make it work, seems like updateQueryData callback is not called.

Keep in mind that at the moment when getAll function gets called, there isn't any getById queryes in cache! I am not sure if that's issue here..

This is my api code for getAll(list view):

getAll: builder.query({
      query: () => `getAll`,
      providesTags: (result) =>
        result
          ? 
            [
              ...result.map(({ id }) => ({ type: "Fruits", id })),
              { type: "Fruits", id: "LIST" },
            ]
          : [{ type: "Fruits", id: "LIST" }],
      async onQueryStarted(_, { dispatch, queryFulfilled }) {
        try {
          const { data } = await queryFulfilled;
          //here I am getting my list...
          data.map((fruit) => {
            dispatch(
              fruitApi.util.updateQueryData("getById", fruit.id, (draft) => {
                console.log("hi mom");
                return Object.assign(draft, fruit);
              })
            );
          });
        } catch (e) {
          console.log(e);
        }
      },
    }),

And this is my getById(details view) api code:

getById: builder.query({
      query: (id) => `getById?id=${id}`,
      providesTags: (result) =>
        result
          ? [{ type: "Fruits", id: result.id }] : [],
    }),
@phryneas
Copy link
Member

updateQueryData only updates existing data for existing cache entries. It is not meant to add new cache entries.

@WingsDevelopment
Copy link
Author

Is there any other way to add new data to cache?

@markerikson
Copy link
Collaborator

Not exactly at the moment. There's an open PR to add something along those lines, but it needs more work:

#2007

@WingsDevelopment
Copy link
Author

Hey guys sorry to bother you again, I am really trying to learn rtk-query, and I'm trying a little bit different usecase now, and that is to optimistically update existing query data, and again updateQueryData callback is not getting called..
This is my update mutation:

updateFruit: builder.mutation({
      query(request) {
        return {
          url: `update`,
          method: "PUT",
          body: {
            id: request.id,
            name: request.name,
            description: request.description,
          },
        };
      },
      async onQueryStarted(request, { dispatch, queryFulfilled }) {
        console.log(request); //request is correct
        const id = request.id;
        console.log(id); //id is correct
        const optimisticUpdate = dispatch(
          //here i tried id, { id }, request.id, even putting hardcoded number, nothing seems to work...
          fruitApi.util.updateQueryData("getById", id, (draft) => {
            console.log("hi mom"); //I'm not getting this..
            console.log(request);
            return Object.assign(draft, request);
          })
        );
        try {
          await queryFulfilled;
        } catch (e) {
          optimisticUpdate.undo();
          console.log(e);
        }
      },
      invalidatesTags: (_result, _error, { id }) => [
        { type: "Fruits", id: "LIST" },
        { type: "Fruits", id: "TOTAL-COUNT" },
        { type: "Fruits", id: "PARTIAL-LIST" },
        { type: "Fruits", id },
      ],
    }),

Update is called after visiting (and fetching) getById route with same id that I am updating.
This is my getById query:


getById: builder.query({
      query: (id) => `getById?id=${id}`,
      providesTags: (result) =>
        // is result available?
        result
          ? // successful query
            [{ type: "Fruits", id: result.id }]
          : [],
    }),

And this is my api config in case you need it..


export const fruitApi = createApi({
  reducerPath: "fruitApi",
  baseQuery: fetchBaseQuery({ baseUrl: "http://localhost:3010/" }),
  refetchOnFocus: true,
  // refetchOnMountOrArgChange: true,
  tagTypes: ["Fruits"],
  endpoints: (builder) => ({

I don't know if I should open different issue or it is okay to ask you here...

@markerikson
Copy link
Collaborator

It's hard to see what you're doing with those snippets. Can you post an entire example as either a CodeSandbox, a Github repo, or a Replay ( https://replay.io/record-bugs )?

@WingsDevelopment
Copy link
Author

WingsDevelopment commented Apr 17, 2022

Hello I'm sending you Github repo here: https://github.com/WingsDevelopment/rtk-query-demo
Pipeline starts in ui/single-element.jsx component, that calls updateFruit mutation.

@phryneas
Copy link
Member

@WingsDevelopment you sohuld use the exact argument that you are putting into the useQuery hook when you call it.

If you call it useGetByIdQuery(foo), then use dispatch(fruitApi.util.updateQueryData("getById", foo, ...

@WingsDevelopment
Copy link
Author

I knew that already, but it seems there is something I don't understand because I thought that I am already doing that...

rtk-query-question

I am passing everywhere: id

I am not sure if you saw code for getAll and you are answering because of that?... But my qustion is about getById and updateFruit under the comment 'THIS DOESN'T WORK' that can be found here: https://github.com/WingsDevelopment/rtk-query-demo/blob/main/src/api/FetchDataApi.js

@WingsDevelopment
Copy link
Author

WingsDevelopment commented Apr 17, 2022

Okay I got it, there was a problem with the type in this case after converting id to string in line before it started working.. I guess adding this at least to documentation (correct me if I am wrong but I haven't found anything about this), or loging some warning/error would be nice.. :D But I'm glad I got it to work.. Thanks for help!

@mh7777777
Copy link

mh7777777 commented Jul 19, 2022

Okay I got it, there was a problem with the type in this case after converting id to string in line before it started working.. I guess adding this at least to documentation (correct me if I am wrong but I haven't found anything about this), or loging some warning/error would be nice.. :D But I'm glad I got it to work.. Thanks for help!

Thanks man, that was an issue on my side too... I spent a lot of time debugging this. 😕

@arquadrado
Copy link

Hi, guys. Sorry for hijacking the thread but it's kind of related.

I was also not having the updateQueryData callback called but thanks to this thread I found out that I was not passing the same argument as I was passing to the original query. After making that change the callback started being called.

Now the problem is that the callback has as argument a draft and for me this draft is a Proxy with which I can do nothing. The endpoint cache that I am trying to update is a list so I was expecting to be able to do something like draft.push(newEntry) but obviously it fails. Any clues on what I might be missing?

@markerikson
Copy link
Collaborator

@arquadrado : assuming you returned an array of data earlier from the response, yes, I would expect that you could do draft.push().

If you try import { current } from "@reduxjs/toolkit", and do console.log(current(draft)), what does that show?

@arquadrado
Copy link

@markerikson thank you for input. The problem was indeed that we were transforming the response of the list endpoint with the transformResponse function and it was no longer an array but an object. Thanks again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants