Reputation: 575
I am struggling to get my head around async/await.
I have the following code which calls:
submitHandler()
which posts a form's inputs to Google sheets const scriptURL =
'GOOGLE SCRIPT URL'
const form = document.forms.emailform
fetch(scriptURL, { method: 'POST', body: new FormData(form) })
.then(response => {
console.log('Success!', response)
setFormSuccess(1)
})
.catch(error => {
console.error('Error!', error.message)
setFormSuccess(2)
})
}
childRef.current.upload()
which posts a file to S3...but I need to wait for the results from both these functions before I call another function to open a modal and pass in the results of these two functions.
Can anybody help me please?
Many Thanks
async function onSubmit() {
setTimeout(() => {
submitHandler()
childRef.current.upload()
}, 1000)
}
//I want to wait for onSubmit to complete and then call another function which sets state and then launches a modal
EDIT: I for got to mention in the original question that I have tried await in all of the functions I call, but none of them work
Upvotes: 0
Views: 1315
Reputation: 758
I think you are just missing some "await" statements. Also I modified the timeout.
async function onSubmit() {
let sleep = function (ms) {
return new Promise(resolve => setTimeout(resolve, ms))
}
await sleep(1000)
await submitHandler()
await childRef.current.upload()
}
//I want to wait for onSubmit to complete and then call another function which sets state and then launches a modal
Also in the submitHandler() you are not correctly using async-await. You are using the .then methods, which cannot be easily combined with the await.
async submitHandler() {
const scriptURL = 'GOOGLE SCRIPT URL'
const form = document.forms.emailform
try {
let response = await fetch(scriptURL, { method: 'POST', body: new FormData(form) })
console.log('Success!', response)
setFormSuccess(1)
} catch(error) {
console.error('Error!', error.message)
setFormSuccess(2)
}
}
If you want to still catch errors, you have to wrap the fetch in a try block.
Upvotes: 1
Reputation: 143
Your function should return Promise
. So return your fetch()
submitHeader(){
const scriptURL =
'GOOGLE SCRIPT URL'
const form = document.forms.emailform
return fetch(scriptURL, { method: 'POST', body: new FormData(form) })
.then(response => {
console.log('Success!', response)
setFormSuccess(1)
return response;
})
.catch(error => {
console.error('Error!', error.message)
setFormSuccess(2)
})
}
So at you main function you could
async function onSubmit() {
setTimeout(() => {
const response = await submitHandler()
// Your response will be available here
console.log(response);
childRef.current.upload()
}, 1000)
}
Upvotes: 0
Reputation: 5190
You can use Promise.all() to await multiple Promises, like so
const result = await Promise.all([submitHandler(), childRef.current.upload()]);
Upvotes: 1
Reputation: 4991
The first thing is that you need to mark the callback to setTimeout
as async
if you want to await
inside it.
But setTimeout
uses callbacks and thus deviate from the control flow you desire. Thus I'd use a simple promise wrapper to make it happen :
const promiseSetTimeout = (cb, delay) => new Promise((resolve, reject) => {
setTimeout(async () => {
const ret = await cb();
resolve(ret);
}, delay);
});
Thus you can await on it and have the desired control flow.
function onSubmit() {
return promiseSetTimeout(async () => {
await submitHandler();
await childRef.current.upload();
}, 1000);
}
Upvotes: 0