The load-more button that never stops
A paginated feed keeps showing 'Load more' even on the last page — triggering an extra empty fetch on every visit. The data is correct, but the metadata lies.
A bug report landed from the frontend team: the feed component is firing an extra API call on every visit. Users on the last page of results still see a "Load more" button — clicking it returns an empty array and a brief flash of a loading spinner. Not a crash, but bad enough to file a ticket.
The culprit is paginate() in src/paginate.ts. It returns a PaginationResult object with data, navigation flags, and page metadata. Three of its four tests pass — only one is red, and it points straight at the bug.
The situation
The function looks reasonable at a glance. It clamps the page to valid bounds, slices the right items, and populates the result. But one of the returned fields is always slightly off — and that one field is what the UI reads to decide whether to render the "Load more" button.
Three tests pass. One fails:
it("hasNext is false on the last page", () => {
const result = paginate(ITEMS, 3, 3) // last page of 4
expect(result.hasNext).toBe(false)
})What you'll do
- Run the tests and read the failure output — it tells you what
hasNextreturns vs. what it should. - Trace through the logic for the last page: what is
safePage? What istotalPages? What does the current condition evaluate to? - Fix the condition so
hasNextisfalseon the last page andtrueon every other page.
Done when
All four tests pass. The fix is a single expression — no restructuring needed.