I have a function that uploads multiple files one at a time and for that, I have to wait till all of them are uploaded and then I want to call a function.
I've two hooks
const [attachments, setAttachments] = useState([]);
const [uploadedAttachments, setuploadedAttachments] = useState([]);
attachments
contains the selected file and then when a file is uploaded I'm storing some metadata about it in uploadedAttachments
which I need to send with another call.
So on the upload button press, I'm calling this function:
async function uploadAttachments(userID, id) {
await Promise.all(
attachments.map(async (val, index) => {
await services.uploadAttachment(val, userID, id).then((res) => {
setuploadedAttachments([...uploadedAttachments, { "name": res.name, "size": res.size }])
}).catch((error) => {
Alert.alert("Error", error)
})
})).then(() => {
console.log(JSON.stringify(uploadedAttachments))
}).catch((e) => {
console.log("ERROR: " + e)
})
}
The JSON.stringify(uploadedAttachments)
prints []
but if I console.log
the res
before setuploadedAttachments
is called I see I'm getting the response and that means that the setuploadedAttachments
is being updated but the place where I'm print it shows me empty array. So, how do I make sure that it await
and so that I can see it when the Promise.all
is finished?
UPDATE
My question is not a duplicate of useState set method not reflecting change immediately
I'm waiting for all the promises to fulfill. Each promise when return me some data I add it to an array which I'm handling using the useState
hook. Yes, it's not reflecting the changes immediately and I have tried putting it in the useEffect
hook as suggested in the supposed duplicate question.
useEffect(() => {
setuploadedAttachments([...uploadedAttachments, { "name": res.name, "size": res.size }])
}, [])
It shows the alert with Error
in the title but no error message. In short, it's not working.
UPDATE 2
Based on the comments I did
async function uploadAttachments(userID, id) {
await Promise.all(
attachments.map(async (val, index) => {
await services.uploadAttachment(val, userID, id).then((res) => {
return res
}).catch((error) => {
Alert.alert("Error", error)
})
})).then((responses) => {
console.log(JSON.stringify(responses))
}).catch((e) => {
console.log("ERROR: " + e)
})
}
The services.uploadAttachment
function is
async function uploadAttachment(val, userID, id) {
let fullURL = BASE_URL + '/uploadFile'
const data = new FormData()
data.append(...
const config = {
...
};
return new Promise((res, rej) => {
axios.post(fullURL, data, config).then((response) => {
res(response.data)
}).catch((error) => {
console.log(error)
Alert.alert("Error Occured", error);
})
})
}