Implement a Debounced Autocomplete
Debounce keystrokes, cancel stale requests, and render suggestions in order so the list always reflects the latest query without flooding the API.
Task
Build an autocomplete input that queries the server after typing pauses and ignores superseded responses.
When to use this
Typing fires one request per character, responses arrive out of order, and the dropdown shows suggestions for a query the user already changed.
Prerequisites
- An endpoint that returns suggestions for a query
- AbortController or a request library that supports cancellation
Steps
1. Debounce the input by a short delay before issuing a request.
Expected output: Requests fire only after typing pauses.
2. Abort the previous in-flight request when a new one starts.
curl "https://api.example.com/search?q=typescr"Expected output: Only one suggestion request is active at a time.
3. Tag each request with a sequence number and ignore responses older than the latest.
Expected output: Out-of-order responses never render stale results.
4. Render a loading state, an empty state, and clamp suggestion count.
Expected output: The dropdown never shows an empty flicker or overloads the DOM.
Troubleshooting
Problem
Abort errors surface as failures
Solution
Distinguish AbortError from real errors and ignore the former silently.
Problem
Debounce on every keystroke still slow
Solution
Combine debounce with a minimum query length and cancel-on-empty.
Limitations
- Debounce adds latency; for very fast servers a shorter delay or throttling may feel better.
- Server-side ranking quality matters more than client timing and cannot be fixed by debouncing.
Context
Build an autocomplete input that queries the server after typing pauses and ignores superseded responses. Typing fires one request per character, responses arrive out of order, and the dropdown shows suggestions for a query the user already changed.
Steps
- Debounce the input by a short delay before issuing a request. Expected: Requests fire only after typing pauses.
- Abort the previous in-flight request when a new one starts. Expected: Only one suggestion request is active at a time.
- Tag each request with a sequence number and ignore responses older than the latest. Expected: Out-of-order responses never render stale results.
- Render a loading state, an empty state, and clamp suggestion count. Expected: The dropdown never shows an empty flicker or overloads the DOM.
let seq = 0;
async function search(q) {
const my = ++seq;
const data = await (await fetch(`/api/search?q=${encodeURIComponent(q)}`)).json();
if (my === seq) render(data);
}
Verify
- Requests fire only after typing pauses.
- Only one suggestion request is active at a time.
- Out-of-order responses never render stale results.
- The dropdown never shows an empty flicker or overloads the DOM.
Limits
- Debounce adds latency; for very fast servers a shorter delay or throttling may feel better.
- Server-side ranking quality matters more than client timing and cannot be fixed by debouncing.