DEV Community

Cover image for Async Form Posts With a Couple Lines of Vanilla JavaScript

Async Form Posts With a Couple Lines of Vanilla JavaScript

Rik Schennink on January 24, 2019

In this tutorial, we will write a tiny JavaScript event handler that will post our HTML forms using fetch instead of the classic synchronous redire...
Collapse
 
mikeodev profile image
Mike

Awesome write up! I definitely learned some things I'll be implementing into my future form creations. I really appreciate the details and explanations you gave for each line of code. Thank you!

Collapse
 
rikschennink profile image
Rik Schennink

So glad to hear that Mike! Thanks so much for taking the time to write this feedback.

Collapse
 
joshuakb2 profile image
Joshua Baker

Is there a reason you're not using async/await in 2019? I think the title of this article is slightly misleading.

Collapse
 
rikschennink profile image
Rik Schennink

Honestly, I haven’t gotten around to using it enough for me to feel comfortable advising others to use it.

I wonder if the prevent default call would still run while the fetch request has started, I guess not as async/await makes it synchronous so in that sense I suspect without can be better in this case.

I understand what you mean about the title being misleading, but without the edge cases (and all the comments) it truly is only a couple (okay not two) lines of JS. 🙃

Collapse
 
jf1 profile image
Jed Fox

You could use an II(AA)FE to use async-await:

document.addEventListener('submit', e => {
  const form = e.target;
  const statusBusy = form.querySelector('.status-busy');
  const statusFailure = form.querySelector('.status-failure');

  (async () => {
    const res = await fetch(form.action, {
      method: form.method,
      body: new FormData(form)
    })
    const doc = new DOMParser().parseFromString(await res.text(), 'text/html')

    const result = document.createElement('div');
    result.innerHTML = doc.body.innerHTML;
    result.tabIndex = -1;
    form.parentNode.replaceChild(result, form);
    result.focus();
  })().catch(err => {
    Array.from(form.elements).forEach(field => field.disabled = false);
    lastActive.focus();

    statusBusy.hidden = false;
    statusFailure.hidden = false;
  });

  // ...

});