Call Mutation again on Error?

Hey guys, if my token is expired, I need to refresh it and then call the API again. Whats the best way to do this in react query? I can't find a way to "re-call" the mutation on error. Should I be doing this in axios interceptors?
16 Replies
theo (t3.gg)
theo (t3.gg)•3y ago
Ooo this is actually a really good question. Hrm Thought on this a bit. If the reason is because the token has expired, I'd probably do that check as part of the mutation itself Either that or run a poll behind that checks This is a hard one and I'm open to other takes
arkitos
arkitos•3y ago
For the first one, I don't know if there's a way to check if the token has expired before actually calling the mutation and having it error 403. Not sure I understand the second option, is that for the backend? I would need to ping the backend dev in that case but thinking of a way to handle it on the frontend at least for now because I'm really behind on this feature 😅 ya'll know how it is
theo (t3.gg)
theo (t3.gg)•3y ago
Oh I assumed this was using tRPC and you owned the backend, my bad
arkitos
arkitos•3y ago
AWS lambda fortunately or unfortunately I think the most straightforward way to do this would be with a try catch block with mutateAsync, calling the API again on error after refreshing the token The unfortunate thing with that is I would need to manage the API state manually
theo (t3.gg)
theo (t3.gg)•3y ago
to be fair my trpc is on lambda LUL this is tough
arkitos
arkitos•3y ago
Ok i'm fairly new to tRPC and had no idea this was possible. Bit of a tangent from the initial question but don't you need a monorepo for tRPC to work? The backend stuff is completely separate in my case
theo (t3.gg)
theo (t3.gg)•3y ago
Yes tRPC requires monorepo, very much "backend for frontend" Re: retry stuff, does onError fire for every retry? Curious if the builtin retries can be forced to work this way
arkitos
arkitos•3y ago
Tried. Nope 😦 onError fires after all the retries have been made
theo (t3.gg)
theo (t3.gg)•3y ago
That's pretty lame. RIP 😦 I think I'd do it in the mutation but I really think the best bet would be to "validate the token externally"
arkitos
arkitos•3y ago
Another unfortunate thing apart from handling state manually is I would need to use the same trycatch logic for every API that needs to handle expired tokens could you elaborate on the externally part?
theo (t3.gg)
theo (t3.gg)•3y ago
const useValidToken = () => {
const {data} = useQuery("token", doTokenValidation, {refreshInterval: 60000})
}

...
const validToken = useValidToken();
const useValidToken = () => {
const {data} = useQuery("token", doTokenValidation, {refreshInterval: 60000})
}

...
const validToken = useValidToken();
arkitos
arkitos•3y ago
That's... pretty graceful. I'll definitely tinker around with this method and see how it works. Pretty sure this means the token would always be valid right? And to attach it to axios headers I would need to useEffect on it and add it to the common headers.
theo (t3.gg)
theo (t3.gg)•3y ago
How do you get the headers? I would probably make a useHeaders hook and do this in that
arkitos
arkitos•3y ago
const generateToken = useMutation(getToken, {
onSuccess(res) {
instance.defaults.headers.common['authorization'] = res?.data?.token;
},
});
const generateToken = useMutation(getToken, {
onSuccess(res) {
instance.defaults.headers.common['authorization'] = res?.data?.token;
},
});
Just doing this right now to attach the token to headers whenever I get it oh and yes... getting the token is a mutation not a query 🙂 which means I cant do the react query builtin refreshInterval. Frick.
theo (t3.gg)
theo (t3.gg)•3y ago
Why is this the case?
arkitos
arkitos•3y ago
Need to pass access and secret keys in the POST body. The use case is a bit different for the app I'm working on because of multiple tenants and as such thats how the backend dev ended up making it
Want results from more Discord servers?
Add your server