Paginate the shipments list
Angular · Angular · beginner · modification
Moves the shipments screen off the load-everything endpoint onto the paged API. The component keeps a zero-based page index for the pager math, tracks an in-flight flag so the buttons can't double-fire, and shows the human page number in the label. Paged back and forth on the staging account and the list updates as expected.
Ops accounts hold thousands of shipments, which is why the endpoint was paginated; typical accounts span dozens of pages.
Requirements
- Replace the load-everything shipments list with server-side pagination: a Prev/Next pager and a 'Page X of Y' label, showing one page of shipments at a time.
- ShipmentsService.fetchPage(page) forwards its argument untouched as the `page` query param of GET /api/shipments. The API's pages are 1-based: valid pages are 1..totalPages, and any requested page below 1 is clamped to 1 (legacy behavior, kept for old clients).
- Every shipment must be reachable through the pager: page 1 is the first screen, page totalPages is the last, no page repeated.
- The API always reports totalPages >= 1 (an empty account yields one empty page). Pager buttons are disabled while a request is in flight, and Prev/Next are disabled at the first/last page respectively.
- HTTP errors are handled globally by the app's interceptor and are out of scope for this component.
Files touched
- src/app/shipments/shipment-list.component.ts
--- src/app/shipments/shipment-list.component.ts
import { Component, OnInit, inject, signal } from '@angular/core';
-import { Shipment, ShipmentsService } from './shipments.service';
+import { ShipmentPage, ShipmentsService } from './shipments.service';
@Component({
template: `
<ul class="shipments">
- @for (shipment of shipments(); track shipment.id) {
+ @for (shipment of page()?.items ?? []; track shipment.id) {
<li>{{ shipment.reference }} — {{ shipment.status }}</li>
}
</ul>
+ <nav class="pager">
+ <button (click)="goTo(pageIndex() - 1)" [disabled]="loading() || pageIndex() === 0">
+ Prev
+ </button>
+ <span>Page {{ pageIndex() + 1 }} of {{ page()?.totalPages ?? 1 }}</span>
+ <button
+ (click)="goTo(pageIndex() + 1)"
+ [disabled]="loading() || pageIndex() + 1 >= (page()?.totalPages ?? 1)"
+ >
+ Next
+ </button>
+ </nav>
`,
})
private service = inject(ShipmentsService);
- protected shipments = signal<Shipment[]>([]);