I'm trying to use react-query with an Ionic React webapp on a Drupal backend. I have a React form (using react-hook-form) that lets the user optionally attach an image to their user account.
Ionic interacts with Drupal via JSON:API, and Drupal's JSON:API requires that the file be uploaded first, and then the file be attached to the user account, so I need two mutations.
My question is: how can I implement the two mutations so that the file is uploaded, and then, if it was successful, I update the user account using the second mutation, and if the upload was not successful, I show an error?
Currently my code looks like this:
AddPhoto.tsx
const onSubmit = async (userData: JsonFormUser) => {
if (userData.photoType === 'other') {
const myJsonData : JsonDataUserPhotoOther = {
data: {
id: userObject.id,
type: 'user',
attributes: {
photoType: userData.photoType,
photoName: userData.photoName,
},
},
};
// Upload the new photo.
if (imageSrc && !imageSrc.includes(baseUrl)) {
const myCroppedImgBlob = await getCroppedImg(
imageSrc,
croppedAreaPixels,
);
mutatePhotoFile.mutate(myCroppedImgBlob);
// Todo: Find a way to run this only if the mutate is successful.
mutateUser.mutate(myJsonData);
So what I want to do is run mutateUser if mutatePhotoFile is successful.
Here's mutatePhotoFile:
const mutatePhotoFile = useMutation(
(
myImageBlob: string,
) => postFileBlobWithUserAuth(
`${postUserUrl(userObject.id)}/field_ref_image`, myImageBlob,
), {
onSuccess: (response: ResponseMutatePhoto) => {
userDispatch({ type: 'setPhoto', payload: response });
},
onError: () => {
setShowFileAlert(true);
},
},
);
I tried to call mutateUser within the onSuccess of mutatePhotoFile, but I didn't have access to the myJsonData variable because that is scoped to the onSubmit function.
So then I tried using useState to store myJsonData, but mutatePhotoFile finishes resolving before the useState updates.
I am guessing there is probably a pattern for handling this in Javascript that I just don't know.
To summarize,
- The user clicks a submit button.
- I fire one react-query mutation that uploads the file to Drupal.
- If there is an error, I show it to the user. If there is no error, I immediately fire another mutation that updates the user account.
What kind of pattern can I use to implement this?