main.js — wiring up search
In the code column — main.js with search. We add a fourth loose variable, searchQuery, a derived visiblePictures() (the filtered pictures), and a debounced input listener.
First, index.html needs a search field:
<input type="search" id="search" placeholder="Search by title…" autocomplete="off">
The key line is the input listener wrapped in debounce:
searchInput.addEventListener('input', debounce((e) => {
searchQuery = e.target.value.trim();
render(); // filter ONLY once settled
}, 250));
And render() always draws from derived data:
function render() {
renderGallery({ isLoading, error, pictures: visiblePictures() });
}
Verify. Serve it and type into the search box:
1. Type "moon" → the grid narrows to titles containing "moon".
2. Clear it → all pictures return.
3. Type something absent → you see "No pictures match…" (the empty state from lesson 6).
Gotcha (without debounce). Temporarily remove
debounce(leave just(e) => {...}) and, in the browser's "Performance" or withconsole.count()inside, watch how many timesrender()fires while typing. Every keystroke is a full grid re-render. For local search it may "work", but the habit is bad: add server search and it becomes a flood of requests. Events that "rain down" always get wrapped in debounce.
Notice (it's piling up). We now have four loose variables:
pictures,isLoading,error,searchQuery. Still manageable. But the collection (lesson 10) will add sorting, pagination, its own search… In lesson 8 we'll see where this leads.