Theory

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.