A table as a derived view of state
We have favorites (lesson 9). Now let's show them as a collection table — with sortable columns, pagination and search. This is the first feature built entirely on lesson 9's pub/sub: the table reads getState(), and actions (sort, paginate) call notify(), and the table re-renders itself.
The key idea: a table is a derived view of state. We don't store a "sorted list" or a "current page" separately — we compute them from state on every render:
favorites ──filter(search)──▶ ──sort(column, direction)──▶ ──slice(page)──▶ rows
Three operations, always in the same order: filter → sort → slice. Swap the order (e.g. slice before filtering) and page counts "drift". So getFilteredFavorites() returns a ready list, and renderCollection just slices out the page.
Three controls:
- Sorting. Click a column header — sort by it; click the same one again — flip the direction (asc ↔ desc).
- Pagination.
Math.ceil(rows.length / pageSize)pages;slice(start, start + pageSize)cuts out the current one. - Search. Across title, notes AND tags.
And one sneaky trap waits when sorting — Array.sort() doesn't behave the way you'd expect.