Yo folks, I’m wiring up a signup form and I’m trying to validate a username as the user types, but I keep hitting a failure mode where slower responses overwrite newer ones and the field toggles between valid/invalid.
const input = document.querySelector('#username');
const status = document.querySelector('#status');
let controller;
input.addEventListener('input', async (e) => {
const value = e.target.value.trim();
if (!value) return;
controller?.abort();
controller = new AbortController();
status.textContent = 'checking...';
const res = await fetch(`/api/username?u=${encodeURIComponent(value)}`, {
signal: controller.signal
});
const { available } = await res.json();
input.setCustomValidity(available ? '' : 'Taken');
status.textContent = available ? 'ok' : 'taken';
});
What’s the cleanest way to make this reliable so aborted/older requests can’t stomp newer validation, without making the UX laggy or the tests flaky?