skip to Main Content

I have the following code:

 const form = document.querySelector('form');
   form.addEventListener('submit', handleSubmit());

    async function handleSubmit(event) {
        const url = new URL(form.action);
        const formData = new FormData(form);
    
        @type {Parameters<fetch>[1]}
        const fetchOptions = {
            method: form.method,
            body: formData,
        };
    
        const response = await fetch(url, fetchOptions);
        alert (response);
    
        event.preventDefault();
      }

With it, im trying to upload a file to an external api and receive a server generated id once the upload is complete. However, when the upload completes, im redirected to the api response body containing the id. How do I prevent the redirect and instead get the id stored into a variable?

fetch(url, fetchOptions)
    .then(function(response)
            {
              return response.json();
            }).then(async function(response)
            {
             alert(response);
            });

I tried the above and was still redirected. I also tried moving the preventDefault call up to the top of the function as suggested by @Quentin, to no avail.

2

Answers


  1. You need to call preventDefault before the function ends or goes to sleep and returns control to it’s called. i.e. before you hit an await.

    Since you are calling preventDefault too late, the regular form submission continues causing the browser to navigate.

    Login or Signup to reply.
  2. JavaScript executes your code synchronously until it meets await

    event.preventDefault() is used to cancel the default browser behavior on form submission. It works because a browser uses only 1 thread for JS execution, so the order is the following:

    1. Form submit event fired
    2. handleSubmit function called
    3. Default browser action if it is not canceled

    Browser expects that handleSubmit is a regular function and does not await it. Any async function executes as a regular one until the first await, so in your case order is the following:

    1. Form submit event fired
    2. handleSubmit function is called and executes until the first await
    3. Default browser action
    4. Browser doing redirect so the rest of handleSubmit makes no sense.

    I always recommend adding event.preventDefault() on top of an event handler if you going to cancel its default behavior. You can try this variant:

    async function handleSubmit(event) {
        event.preventDefault();
    
        const url = new URL(form.action);
        const formData = new FormData(form);
    
        const fetchOptions = {
            method: form.method,
            body: formData,
        };
    
        const response = await fetch(url, fetchOptions);
        alert(JSON.stringify(await response.json(), null, 2))
    }
    
    form.addEventListener('submit', handleSubmit);
    <form action="https://jsonplaceholder.typicode.com/posts" method="POST" id="form">
      <input value="Post Title" name="title"/>
      <button type="submit">submit</button>
    </form>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search