Reputation: 7743
I do not get any statuses of the promises in my requests
array when resolving with Promise.all
.
What am I doing wrong here as I thought that using axios
post
method would return a promise?
const doUpload = async (fileList: FileList) => {
const requests: Array<void | AxiosResponse<any>> = [];
Array.from(fileList).forEach(async file => {
const formData = new FormData();
const blob = new Blob([file]);
formData.append(file.name, blob);
requests.push(
await axios
.post(
'https://jsonplaceholder.typicode.com/posts',
{
...formData,
},
{
headers: {
'Content-Type': 'multipart/form-data',
},
onUploadProgress: (progressEvent: ProgressEvent) =>
handleUploadProgress(progressEvent, file.lastModified),
}
)
.catch(error => {
handleUploadError(file.lastModified);
})
);
});
try {
const data = await Promise.all(requests);
console.dir(data);
} catch (error) {
console.log(error);
}
};
Upvotes: 0
Views: 916
Reputation: 1074138
Jeremy's right that you have unnecessary await
s in your code, but the primary problem is that you're hiding promise rejection by putting a catch
handler on the promise from post
and then letting that handler complete without either throwing an error or returning anything. That turns rejection into fulfillment with the value undefined
.
Remove the catch
handler (probably) or have it return something that you can use to know the post
failed.
FWIW, here's an example doing the above and using Array.from
's mapping feature (since you're doing a mapping operation); see comments:
const doUpload = async (fileList: FileList) => {
// Use `map`
const requests = Array.from(fileList, file => {
const formData = new FormData();
const blob = new Blob([file]);
formData.append(file.name, blob);
// No need for `await` here
return axios.post(
'https://jsonplaceholder.typicode.com/posts',
{
...formData,
},
{
headers: {
'Content-Type': 'multipart/form-data',
},
onUploadProgress: (progressEvent: ProgressEvent) =>
handleUploadProgress(progressEvent, file.lastModified),
}
);
// No `.catch` here (or have one, but make it return something useful
});
try {
const data = await Promise.all(requests);
console.dir(data);
} catch (error) {
console.log(error);
}
};
If you need to call handleUploadError
somewhere in there, you might consider using Promise.allSettled
(relatively new) rather than Promise.all
and then calling that for any rejected promises in the array it gives you.
...when resolving with Promise.all.
Just a side note: Using Promise.all
doesn't "resolve" the promises you pass into it. It just observes what happens with them. The promises will settle however they're going to settle whether you use Promise.all
or not.
Some promise terminology that may be helpful:
Upvotes: 3
Reputation: 26360
You are pushing resolved Promises to your array (requests.push(await axios.post())
). Just push Promises without awaiting them(requests.push(axios.post())
). Then Promise.all
can do its job.
const doUpload = async(fileList: FileList) => {
const requests: Array < void | Promise<any> > = [];
Array.from(fileList).forEach( file => {
const formData = new FormData();
const blob = new Blob([file]);
formData.append(file.name, blob);
requests.push(axios.post(/* ... */ ));
});
try {
const data = await Promise.all(requests);
console.dir(data);
} catch (error) {
console.log(error);
}
};
Upvotes: 2