I have a React form with a file as an input, and the onFileChange
saves setFile(e.target.files[0])
(and also toggle a boolean change
). Then when I submit the form:
- I first want to upload this file in the cloud (Cloudinary here),
- wait for the response object (namely the
url
andpublic_id
I'm looking for) - then I add this object (
url
and'public_id
) to the formdata to post to the database backend.
I thought that chaining promises should do the job, but I can't achieve it.
Inside my onFormSubmit
, I first define a promise that captures the none async data:
function init(fd){
fd.append('input1'...)
return Promise.resolve(fd)
}
so I can reuse the formdata to feed the next promise upLoadToCL
that should 'normally' asynchronously append the response object from the cloud to the formdata, with:
init(new FormData).then(res => upLoadToCL(res)).then(res=> ...)
function upLoadToCL(fd) {
if (changed) {
// send 'file' (saved as state variable after input) to the cloud
const newfd = new FormData();
newfd.append("file", file);
newfd.append("upload_preset", "ml_default");
fetch(`https://api.cloudinary.com/v1_1/${cloudName}/upload`, {
method: "POST",
body: newfd,
})
.then((res) => res.json())
// append the formdata argument 'fd' with the result
.then((res) => {
setPhoto(res);
fd.append("event[directCLUrl]", res.url);
fd.append("event[publicID]", res.public_id);
})
.catch((err) => {
throw new Error(err);
});
return Promise.resolve(fd);
}
}
I checked that the first promise works and sends to the second promise a 'prefilled' formdata. Then the post request works, and returns a response as I can see that the state variable photo
is updated some time in the futur. However, the promise itself returns a void formdata, even without chaining:
upLoadToCL(new FormData())
.then(res=> {
for (let [k,v] of res){
console.log(k,v)
}
})
returns nothing.