0

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

1

4 Answers 4

1

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.

Sign up to request clarification or add additional context in comments.

7 Comments

Thanks sorry I forgot to mention that the await submitHandler() give an error that await is only allowed in async functions
I was too fast, I have edited my answer. I hope it helps :)
thanks @kevin. That comes up up with 'await' has no affect on this type of expression
on the submitHandler() function. I have added function this to the question now
This is great thanks so much @kevin. Could you give me a steer on the fetch block for the catch equivalent
|
1

You can use Promise.all() to await multiple Promises, like so

const result = await Promise.all([submitHandler(), childRef.current.upload()]);

1 Comment

Thanks @riwen. Although Kevinkreps answer sorted my problem out I also need this to await the second function too
0

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);
}

6 Comments

Thanks @Vivick I am getting promiseSetTimeout is not defined
You did copy the implementation I gave you in the same file (or imported it if it's somewhere else)?
Thanks yes In the same file - I just coped and pasted. It also has an error that await has no effect on this type of expression for the await submitHandler()
That's probably because it does not return a promise
Thanks I have amened the question to include the submitHandler(). Any thoughts?
|
0

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)
            }

5 Comments

Thanks I forgot to mention that I had tried await on all the functions and none of them worked. I will amend my question now
but it is important what is your function returning await could be uset only with Promise return.
The submit handler function posts to a google script with a fetch, then, catch that changes state on then and catche depending on whether the fetch is succesful or not. Sorry to be so dumb on this! :-)
could you show code snippet please? I is impossible to help you when we do not have real returns of your functions
Thanks @Filip I have added the code for the submitHandler() to original question. Please let me know if you need anything else

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.