How do I stop async validation from showing stale errors in a form?

What’s up everyone? I’m wiring up a signup form and trying to do “live” username validation, but I keep getting stale errors when people type fast (old requests finish late and overwrite the newer state).

let currentController;

async function validateUsername(name) {
  currentController?.abort();
  currentController = new AbortController();

  const res = await fetch(`/api/username?u=${encodeURIComponent(name)}`, {
    signal: currentController.signal
  });
  const data = await res.json();
  return data.available;
}

input.addEventListener('input', async (e) => {
  const name = e.target.value;
  setStatus('checking');
  try {
    const ok = await validateUsername(name);
    setError(ok ? '' : 'Taken');
  } catch (err) {
    setError('Network error');
  }
});

What’s the cleanest way to handle aborts vs “ignore out-of-date responses” so I don’t flash bogus errors (and also don’t label aborted requests as network failures)?

1 Like