Skip to main content

Autocomplete (Online API)

Difficulty: Advanced

Problem Statement

Fetch remote suggestions (GitHub users) based on debounced search input.

Live Demo

Try the running app below — this is the target behavior for the challenge.

Autocomplete (Online API) — Live Demo

    What Interviewers Expect

    • Debounce API calls.
    • Loading and error states.
    • Ignore/cancel stale responses.

    Step-by-Step Implementation

    Step 1 — Debounced fetch

    Delay network call until user pauses typing.

    timer.current = setTimeout(() => search(q), 400);

    Step 2 — Fetch + render

    Call GitHub search API and map results.

    fetch(`https://api.github.com/search/users?q=${q}&per_page=5`)

    Step 3 — Cleanup

    Clear timeout on unmount to avoid leaks.

    useEffect(() => () => clearTimeout(timer.current), []);

    Complete Implementation

    Copy-paste ready single-file solution. Use this as your reference after attempting the challenge yourself, or paste it into CodeSandbox / StackBlitz to run locally.

    App.jsx
    import React, {useCallback, useEffect, useRef, useState} from 'react';

    export default function App() {
    const [term, setTerm] = useState('');
    const [users, setUsers] = useState([]);
    const [loading, setLoading] = useState(false);
    const timer = useRef(null);

    const search = useCallback((query) => {
    if (!query.trim()) {
    setUsers([]);
    return;
    }

    setLoading(true);
    fetch(`https://api.github.com/search/users?q=${encodeURIComponent(query)}&per_page=5`)
    .then((response) => response.json())
    .then((data) => setUsers(data.items || []))
    .catch(() => setUsers([]))
    .finally(() => setLoading(false));
    }, []);

    useEffect(() => () => clearTimeout(timer.current), []);

    const onChange = (event) => {
    const query = event.target.value;
    setTerm(query);
    clearTimeout(timer.current);
    timer.current = setTimeout(() => search(query), 400);
    };

    return (
    <div>
    <input
    value={term}
    onChange={onChange}
    placeholder="Search GitHub users"
    />
    {loading && <p style={{color: '#666'}}>Loading…</p>}
    <ul>
    {users.map((user) => (
    <li key={user.id}>{user.login}</li>
    ))}
    </ul>
    </div>
    );
    }

    Final Checklist

    • UI works for primary flow
    • Edge cases handled (empty/disabled/loading where relevant)
    • State updates are immutable
    • Components are readable and reasonably split
    • You can explain trade-offs out loud in an interview

    Next Challenge

    Continue to the next item in the sidebar when you're comfortable implementing this from scratch in 30–45 minutes.

    🌟 Join the JavaScript360 community

    Connect with fellow JS developers, and get free interview prep, React challenges, and DSA guides.

    Join on WhatsApp →