Back to Feed
article 3m read

A staff list whose Next button never knew where the end was

The admin staff list in my scheduling app sent pages with no total, so Next never switched off. The server now counts after the search filter and before slicing, caps the page size, and the screen does the page math; saves also refuse rows with no company, since those could never appear on any page.

Article DepthPractice

Flow

Paging steps and what each one prevents

  1. 1Count after the search filter

    Stops the total from counting the whole company instead of the search result.

  2. 2Count before cutting the page

    Stops the total from being just the length of one page.

  3. 3Default and cap the page size

    Stops empty pages from bad input and whole-list grabs from huge sizes.

  4. 4Send the count in a header

    Keeps the body a plain list, so other readers don't break.

  5. 5Turn Next off without a count

    Shows a short list instead of a button that leads to empty pages.

  6. 6Require a company on every save

    Stops rows that no per-company list can show.

The Next button on my staff list never turned off. Not on the last page, and not past it.

The screen is an admin list in my staff-scheduling app. It shows the people at one company, a few at a time. The server sent back each page as a plain list of rows and nothing else. It never said how many rows there were in all. So the screen could not tell where the end was. A full page could mean more rows, or it could mean the list ended right there. The only way to find out was to click past the end and get an empty table.

Filter, then count, then cut

The server now does its work in this order: filter by the search box, count what's left, then cut out the page. The count goes back in a response header, with the page number and page size it used. The order matters. Count too early and you count the whole company, not the search result. Count too late and you count one page. The rows still come back as a plain list, so nothing else that reads them broke.

The screen can now ask for a page size. The server uses a default for bad values and caps big ones, so nobody can pull the whole company in one request by asking for a huge page.

Working out the last page

The screen's arithmetic is small.

The page count is the total divided by the page size, rounded up and never below one, and Next is disabled on the last page.

If the count is missing, it uses the number of rows it just got, which means one page and no Next. A short list is easier to spot than a button that leads nowhere. But if something on the way stripped that header, the rest of the list would be out of reach. The screen also trusts its own page size instead of reading back the one the server used. That only works while its size stays under the cap.

The admin flag

The screen was sending its "hide admins" setting under the wrong name. The server hid admins by default, so the list looked right anyway. It was right by luck. Now the names match.

Saves that need a company

The same day, saving a staff member got stricter. Before, a save could go through with no company on the row. Now a blank company is looked up from the store, and if there's still none, the save fails. This matters for paging because the list is fetched per company. A row with no company can't show up on any page, no matter how good the pager is.

Still open

A few gaps remain:

  • A save can pair one company with another company's store.
  • Old rows with no company, if any exist, aren't fixed.
  • There are no tests for the pager or the save.
  • The server still loads every row for the company before cutting a page.

The store mismatch is the one I'd close first.

Keep reading

Pick up a connected idea or branch into a nearby one.

5 paths forward