retry on custom useInfiniteQuery with graphQL-request
Hi, i'm trying to achieve a custom hook around
useInfiniteQuery that will fetch next page automatically.
The endpoint I have can only return me 1000 entities at max for a single request.
Depending on some parameters, the request can fail if those 1000 entities are too big, so I may need to reduce the amount fetched if that's the case (depending on the first options in variables).
I'm struggling to implement the logic where in case it fail, I can change my graphql-request parameters to lower the number of requested entities.
Let see some code:
5 Replies
afraid-scarletOP•4y ago
The problem is that in the retry callback, where I need to lower the
first param, how can I manage to somehow persist that first param since it will be also checked in the getNextPageParam to see if there's more entities to fetch ?
If I do the following
I will get the next 300 entities without a problem, but then, when RQ fires getNextPageParam, requestExtendedOptions.variables?.first will be back to 1000, and it will not fetch the next page
After further investigation, it seems that I don't understand how does queryFn is used internally.
This code will give me the following logs:
First has changed: 1000
queryFn: 1000
error: [...]
First has changed: 300
queryFn: 1000
error: [...]
queryFn: 1000
error: [...]
etc etc
How can I change my query depending on the error in retry's callback ? Can it be achieved only inside retry ?extended-salmon•4y ago
you are using
first in the queryFn, but it's not part of the query key, so you're getting a stale closure.
I don't think this is how you can use react-query. retries are supposed to retry with the same values. If you want something more custom, you can always just do all the things inside the queryFn, like:
- await a request
- catch error
- if it's size to big, make another request with a smaller size, or multiple requests
- concatenate all responses to one array
the queryFn needs to return one promise that is either fulfilled or rejected, but it is not limited to just one request ...afraid-scarletOP•4y ago
Thanks for the guiding. Moving the logic I had in the
retry directly into the queryFn seems pertinent, since useQuery doesn't need to know about first anymore.
But then, what if I want to look for a next page ? getNextPageParam will need to know how many entities queryFn has fetch (1000 or 300). So handling this in the queryFn have some limitations. Is there a way to solve this ?
I could do the following check inside getNextPageParam to see if there's more to fetch:
lastPage.length >= (requestExtendedOptions.variables?.first ?? 1000) || lastPage.length >= 300 but it start to became too verbose, especially if I need to implement other potential values for first in the futur.
I think I misunderstanding some stuff about how core of useQuery works, but can't wrap my head into a good solution..
PS: Just realize you're the author of that amazing blog about react-query, thanks a lot for that, it's awesomeextended-salmon•4y ago
If you move the fetching to the queryFn - do you really still need an infinite query? Or can it be a normal useQuery?
afraid-scarletOP•4y ago
Depending on some parameters, I could have 50k entities to fetch, and i'm limited by page of 1000, so using normal
useQuery is doable by doing the concatenation myself, but if I can stick with useInfiniteQuery, it simplify stuff a lot for me 😅