tbd_
tbd_

Reputation: 1248

How to force an event callback to wait until async call is resolved?

I have a form that listens to an event called onBeforeSubmit. This event is fired when I submit a form, but will stop the submission if the callback returns false.

Problem

My callback involves an async call to an API. How do I force the event to wait for the promise to resolve before deciding to return false or not? Currently it doesn't wait for the fetch() to resolve - I've tried both async/await and .then() approaches...

What I tried:

Attempt 1:

onBeforeSubmit: async (e) {
  const res = await fetch(url);
  // if res value fails some condition
  return false
}

Attempt 2:

onBeforeSubmit: (e) {
  fetch(url).then( res => {
  // if res value fails some condition
  return false
  })
}

Shouldn't the await force javascript to wait until the fetch resolves before moving on to the next line?

I also noticed that whenever I put the async keyword, it ignores the return false statement and goes ahead with the submission anyways. What's causing that?

EDIT: This is a 3rd party API, so I can't control how onBeforeSubmit behaves :(

Upvotes: 1

Views: 2025

Answers (2)

Sven.hig
Sven.hig

Reputation: 4519

I suggest, to use event.preventDefault() to stop the form from been submitted and then make your fetch request, if the response value is false the form was not submitted in the first place, else you remove the form's event listener onsubmit and then you add a new event listener to submit the form

Here is an example of what your code should look like

var submitform=function sbmform(e){
  e.preventDefault()
  fetchvalue()
}
const form = document.getElementById('myform')
form.addEventListener('submit',submitform,false)

async function fetchvalue(){
  const res = await fetch(url);
 if (res=="to conditon"){  // set your condfiton
       return false
  }
 else{
  form.removeEventListener('submit', submitform, false);
  form.submit()
 }
}

Upvotes: 2

jfriend00
jfriend00

Reputation: 707318

You have an event handler that is expecting a synchronous return value, but you're trying to run an asynchronous operation in that callback. That just won't work in Javascript.

When you run the asynchronous function, your callback function returns immediately at that point and the asynchronous function finishes in its own callback. If you mark the callback async, that just means that it immediately returns a promise. Since the onBeforeSubmit event handler is expecting a boolean to be returned, not a promise, it doesn't work properly.

There is no way in Javascript to make this callback "wait" so it can synchronous return a boolean.

The usual way around this is to always return false so the form is not automatically submitted. Then, run your asynchronous operation and if it succeeds, then you manually submit the form (without further validation) from within that asynchronous completion callback.

Upvotes: 5

Related Questions