Is there a way to force suspense even though response.status is 200?
I am using react-query to communicate with my API. I got this case where i need to fetch some data from API but first i need to check if my DB is loaded (http request is called every 1sec) - there is a seperate endpoint for that which returns something like this: {status: "pending"} while db is not up yet and {status: "loaded"} while DB is up and running. In both cases response.status is 200 and suspense fallback is not rendering while request to the API are still running. Is there some easy way to handle that?
18 Replies
ambitious-aqua•3y ago
Have you opted in to suspense mode and provided a suspense boundary with a fallback?
Actually, are you saying that the request to check the database status resolves successfully regardless of the status of it? If so, that won't cause the component to suspend
flat-fuchsiaOP•3y ago
Request to check the database status is always 200, but it has different body for example: {status: 'loading'} or {status: 'loaded'}. My goal is to keep refetching (in interval) untill response is {status: 'loaded'} and being able to see the suspense fallback rendered.
My suspense is working just fine on other requests but in this case fallback is not rendered after 1st fulfilled api request
ambitious-aqua•3y ago
Yeah, that's how it should behave. If the request has resolved successfully the component won't suspend. I think you need to rethink your approach
Perhaps you could not render the component that makes the API request until the API is ready? That way the query won't run before you render the component that calls it
flat-fuchsiaOP•3y ago
Yeah, probably i'll just use Suspense for all other requests except this one calling the "healthcheck" endpoint. Thought there is some magical way to solve this issue manually.
Thanks for your time and help, really appreciate it 😉
ambitious-aqua•3y ago
Not that I can think of unfortunately. I think conditionally rendering the component that makes the request is ideal. No worries :reactquery:
other-emerald•3y ago
You need to reject the promise from the queryFn that's all 🙂
flat-fuchsiaOP•3y ago
In some axios interceptor?
ambitious-aqua•3y ago
If you reject the promise won't it bubble to the suspense error boundary, and not suspend and poll until the API is ready like the OP wants?
I suppose you could have it retry N amount of times so it continues to suspend until you receive the desired response
I wonder if a simple conditional render would be simpler here though
flat-fuchsiaOP•3y ago
Much simpler I guess. But I'm stubborn and wanted to do it with "my" approach, to see if it's possible 😉
ambitious-aqua•3y ago
I mean it's definitely possible (nearly everything is possible) but I don't think I'd do it personally given what you're describing
Although Dominik is on to something, I think he's suggesting to reject the promise repeatedly until the API is ready and keep retrying the query so the component remains suspended. It's a nice idea
flat-fuchsiaOP•3y ago
I did try rejecting promises but interval was not working as i'd expect
ambitious-aqua•3y ago
Where were you trying to reject and what interval are you referring to?
flat-fuchsiaOP•3y ago
I did try writing interceptor for that
but that might be overkill
ambitious-aqua•3y ago
I think Dominik and I are talking about rejecting from the query function
flat-fuchsiaOP•3y ago
Oh okay, i'll try this approach:)
Setting it up along with retryDelay does the job!
Thank You guys 😉
I'll probably implement the conditional rendering approach, but im glad that it can work with suspense;)
ambitious-aqua•3y ago
Awesome :reactquery:
other-emerald•3y ago
I think Dominik and I are talking about rejecting from the query functionyes. coming back to the original question:
Is there a way to force suspense even though response.status is 200?I thought you were talking about sending errors to the error boundary, sorry. That would work by just rejecting the Promise. To actually trigger the suspense boundary, we have to internally (at the moment, api is subject to change) throw a promise to react, and when that promise resolves, it goes out of the suspense boundary. So I think you would need to keep the promise you return from the queryFn as "non-resolved", even if your fetch is successful. But that means you wouldn't be able to use the interval refetching from react-query. Tricky indeed!
flat-fuchsiaOP•3y ago
I was able to "workaround" it with rejecting promise inside queryFn and setting up the retryDelay + retry count. It was enough for my needs and it works pretty nice ;).
Thanks for helping me out!