Reputation: 728
I have two API calls in onVerificationCodeSubmit
that covering reset password logic. The problem is that newPasswordMutation
executes before setRestorePasswordToken(data.restoreToken)
in verifyCodeMutation
success callback.
How can I wait for it?
Any way I can handle it via React-Query tools?
const { mutateAsync: verifyCodeMutation } = useMutation(verifyCode, {
onSuccess: ({ data }) => setRestorePasswordToken(data.restoreToken),
});
const { mutateAsync: newPasswordMutation } = useMutation(createNewPassword, {
enabled: restorePasswordToken,
onSuccess: () => setPasswordResetSuccessfull(true),
});
const onRestorePasswordSubmit = ({ email }) => {
restorePasswordMutation(email);
};
const onVerificationCodeSubmit = async ({ verificationCode, password }) => {
await verifyCodeMutation({ verificationCode, restoreToken });
newPasswordMutation({ password, restorePasswordToken });
};
Upvotes: 18
Views: 29380
Reputation: 28733
Dependent mutations can basically be solved in 3 different ways:
mutateFn
:const mutate = useMutation((data) =>
axios.post('/something', { data })
.then((somethingResult) =>
axios.put('/somethingElse', { somethingResult })
)
)
<button onClick={() => mutate('data') />
advantage would be one mutation with one loading state. disadvantage would be you can't easily trigger them separately if you'd need to.
mutateAsync
:const mutate1 = useMutation((data) => axios.post('/something', { data }))
const mutate2 = useMutation(somethingResult) => axios.put('/somethingElse', { somethingResult })
<button onClick={async () => {
try {
const somethingResult = await mutate1.muteateAsync('data')
const result = await mutate2.mutateAsync(somethingResult)
} catch {}
}} />
a bit boilerplate-y and you'd need to combine loading states very likely
mutate
and callbacks:const mutate1 = useMutation((data) => axios.post('/something', { data }))
const mutate2 = useMutation(somethingResult) => axios.put('/somethingElse', { somethingResult })
<button onClick={() => {
mutate1.mutate('data', {
onSuccess: mutate2.mutate
})
}} />
separated, but still quite concise. will get messy with more than 2 mutations, and the end-result would only be available in the onSuccess callback of the second mutation if you need it
Upvotes: 43
Reputation: 728
In case it will help someone: I've just executed second mutation in first one onSuccess
const { mutateAsync: verifyCodeMutation } = useMutation(verifyCode, {
onSuccess: ({ data }) => {
setRestorePasswordToken(data.restoreToken);
const password = getValues("password");
newPasswordMutation({ password, restorePasswordToken });
},
});
Upvotes: 10