T
TanStack19h ago
optimistic-gold

Using setQueryData inside a Mutation/QueryCache

So I am in a situation where the API, often throws MFArequired error, so i felt it is not intuitive to constantly throw a callback (onError) in a useMutation to load a state to open a modal. So I saw on the docs we can use Mutation/QueryCache to catch the response. So I am wondering if i will run into any issues and if there is a better way to do this. TLDR: Can i use setQueryData inside QueryClient ? queryClient.ts
import { MutationCache, QueryCache, QueryClient } from "@tanstack/react-query";

export const allAuthQueryClient = new QueryClient({
queryCache: new QueryCache({
onError: (err, query) => {
// some criteria to identify MFA required errors
allAuthQueryClient.setQueryData(["mfaRequired"], { message: err.message });
},
}),
mutationCache: new MutationCache({
onError: (err, _variables, _context, mutation) => {
// some criteria to identify MFA required errors
allAuthQueryClient.setQueryData(["mfaRequired"], { payload: err as any });
},
}),
});
import { MutationCache, QueryCache, QueryClient } from "@tanstack/react-query";

export const allAuthQueryClient = new QueryClient({
queryCache: new QueryCache({
onError: (err, query) => {
// some criteria to identify MFA required errors
allAuthQueryClient.setQueryData(["mfaRequired"], { message: err.message });
},
}),
mutationCache: new MutationCache({
onError: (err, _variables, _context, mutation) => {
// some criteria to identify MFA required errors
allAuthQueryClient.setQueryData(["mfaRequired"], { payload: err as any });
},
}),
});
1 Reply
optimistic-gold
optimistic-goldOP19h ago
here is what i want to avoid, many queries and mutations will throw an error for mfa_re/authenticate required.
export const useLogin = (options?: UseLoginOptions) => {
const { mutate, isPending, error } = $api.useMutation(...LoginKey);

const login = (data: SigninInputType) => {
mutate(
{ body: data },
{
onSuccess: () => {
if (options?.onSuccess) {
options.onSuccess();
} else {

window.location.href = ROUTES.HOME;
}
},
onError: (error) => {
switch (error.status) {
case 401:
if (getFlow(error.data, "mfa_authenticate")?.is_pending && options?.onMFARequired) {
options.onMFARequired();
}
break;
default:
options?.onError?.("An unexpected error occurred.");
}
},
},
);
};
export const useLogin = (options?: UseLoginOptions) => {
const { mutate, isPending, error } = $api.useMutation(...LoginKey);

const login = (data: SigninInputType) => {
mutate(
{ body: data },
{
onSuccess: () => {
if (options?.onSuccess) {
options.onSuccess();
} else {

window.location.href = ROUTES.HOME;
}
},
onError: (error) => {
switch (error.status) {
case 401:
if (getFlow(error.data, "mfa_authenticate")?.is_pending && options?.onMFARequired) {
options.onMFARequired();
}
break;
default:
options?.onError?.("An unexpected error occurred.");
}
},
},
);
};
import { MfaAuthenticateModal } from "../mfa/MfaAuthenticateModal";
import { useEventChannel } from "@/utils/useEventChannel";

type MfaEventPayload = { mode: "login"; userId: string } | { mode: "reauth"; userId: string; sessionId: string };

export const MfaEventModal = () => {
const { event, clear } = useEventChannel<MfaEventPayload>("mfaRequired");

const handleAuthenticate = async (code: string) => {
console.log("MFA code submitted:", code, event);
clear();
};

return <MfaAuthenticateModal isOpen={!!event} onClose={clear} onAuthenticate={handleAuthenticate} />;
};
import { MfaAuthenticateModal } from "../mfa/MfaAuthenticateModal";
import { useEventChannel } from "@/utils/useEventChannel";

type MfaEventPayload = { mode: "login"; userId: string } | { mode: "reauth"; userId: string; sessionId: string };

export const MfaEventModal = () => {
const { event, clear } = useEventChannel<MfaEventPayload>("mfaRequired");

const handleAuthenticate = async (code: string) => {
console.log("MFA code submitted:", code, event);
clear();
};

return <MfaAuthenticateModal isOpen={!!event} onClose={clear} onAuthenticate={handleAuthenticate} />;
};
Providers.tsx
<QueryClientProvider client={allAuthQueryClient}>
<MfaEventModal />
{el}
</QueryClientProvider>
<QueryClientProvider client={allAuthQueryClient}>
<MfaEventModal />
{el}
</QueryClientProvider>

Did you find this page helpful?