In my Next.js app, I'm calling an upload function which contains the then
and catch
functions.
export const uploadDocument = async (url: UploadURLs, file: File) => {
const formData = new FormData();
formData.append("file", file);
await fetch(`${someEndpoint}`, {
method: "POST",
body: formData,
})
.then(() => notify(`Awesome, it worked.`, "success"))
.catch(() => notify("An error occurred.", "error"));
};
Note: The
notify
function is a wrapper function firing a toast notification, and isn't really important to my question.
From my component, I'm calling the uploadDocument
function. Everything is working, but I can't stop router.push(nextPage)
from firing (shown below), regardless of whether the uploadDocument
function succeeds or not.
I want to keep the then
and catch
logic inside the uploadDocument
function, but also would like to have the calling component know whether or not the upload succeeded, so I could prevent the page change.
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
await uploadDocument(
"certificate",
file
)
router.push(nextPage); // This always fires, but should be conditional
};
I tried to capture the result of the function call, but get undefined
regardless of upload success/failure:
const result = await uploadDocument("certificate", file);
if (result.success) router.push(nextPage);
CodePudding user response:
Try this approach:
export const uploadDocument = (url: UploadURLs, file: File) => {
const formData = new FormData();
formData.append("file", file);
return fetch(`${someEndpoint}`, {
method: "POST",
body: formData,
})
};
Then you can catch the error with an try /catch
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
try {
await uploadDocument(
"certificate",
file
)
notify(`Awesome, it worked.`, "success")
router.push(nextPage);
} catch(err) {
notify("An error occurred.", "error")
}
};
CodePudding user response:
I followed the advice of @kemicofa-ghost, as they pointed out in the comments, and arrived at a working solution.
export const uploadDocument = async (url: UploadURLs, file: File) => {
const formData = new FormData();
formData.append("file", file);
try {
await fetch(`${someEndpoint}`, {
method: "POST",
body: formData,
});
notify(`Your file ${file.name} was uploaded successfully`, "success");
return true;
} catch (error) {
notify(
"An error occurred while uploading the file. Please try again.",
"error"
);
return false;
}
};
And then:
const result = await uploadDocument(
"certificate",
companyInfo2.incorporationCertificate
);
if (result) router.push(nextPage);
CodePudding user response:
You can keep your logic in your function:
type UploadResponse = {
error: boolean;
message: string;
}
export const uploadDocument = async (url: UploadURLs, file: File): Promise<UploadResponse> => {
try {
const formData = new FormData();
formData.append("file", file);
await fetch(`${someEndpoint}`, {
method: "POST",
body: formData,
})
return {error: false, message: "Awesome, it worked"}
} catch(e) {
return {error: true, message: "An error occurred"}
}
};
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
const result = await uploadDocument(
"certificate",
file
)
notify(result.message);
if (!result.error) {
router.push(nextPage);
}
};