Interface PaginationState<RT = unknown, E = unknown> sincev5.9.0
interface PaginationState<RT = unknown, E = unknown> {
activePage:
| Readonly<PageCache<RT, E>>
| null;
adoptPage: (request: Future<RT>) => Promise<RT | null>;
loadNext: () => Promise<RT | null>;
loadPage: (url: string) => Promise<RT | null>;
loadPrev: () => Promise<RT | null>;
get activePageRequest(): Future<RT> | null;
get data(): Iterable<ContentItem<RT>>;
get hasNext(): boolean;
get hasPrevious(): boolean;
get nextRequest(): Future<RT> | null;
get pages(): Iterable<Readonly<PageCache<RT, E>>>;
get previousRequest(): Future<RT> | null;
get totalPages(): number;
}Hideconstructor
The per-component, local pagination state. It houses the state that is unique to a single component instance — the active page and navigation — while referencing a shared PaginationCache for the page graph and data.
This is the object yielded by the <Paginate /> component, narrowed by the component's @mode arg to one of its two navigation surfaces so the two APIs cannot be mixed:
- Paged (
@mode="paged", the default): PagedPaginationState — render activePageRequest, navigate with loadPage (what the numbered/relational links call). Reads activePage. - Infinite (
@mode="infinite"): InfinitePaginationState — render data, wrap nextRequest/previousRequest in<Request>for loading state, and grow the view with loadNext/loadPrev.
Both surfaces read the same shared page graph; the mode only selects which API is exposed.
Instances are created via getPaginationState (or by the <Paginate /> component on your behalf), never constructed directly.
Type Parameters
RT
RT = unknown
E
E = unknown
Implements
PagedPaginationState<RT,E>InfinitePaginationState<RT,E>
Properties
activePage
activePage:
| Readonly<PageCache<RT, E>>
| null;The page the paged surface is currently showing. Starts at the page this component first loaded and moves whenever loadPage runs (for example a numbered link is clicked).
Implementation of
PagedPaginationState.activePageadoptPage
adoptPage: (request: Future<RT>) => Promise<RT | null>;Adopts an externally-issued request into this pagination, making its page the activePage — the programmatic entry point for route-driven navigation when managing a PaginationState directly (the <Paginate /> component uses the same mechanism for a changed @request arg).
Awaits the request and verifies that its document is a page of this state's collection (same first — or self — link). On a match, the page is loaded (a page already in the shared cache is reused) and — once its request settles — committed: it becomes the active page, and the infinite surface's run is kept coherent (a page already inside the run leaves it untouched, an adjacent page extends it, a disjoint page resets the run to the adopted page). The commit happens only after the page has loaded, so the previous page stays active — and rendered — while the adoption resolves. Returns the page's document.
Concurrent calls race safely: the latest call wins. An earlier in-flight adoption is superseded and commits nothing, and a loadPage navigation also supersedes a pending adoption (the user's click is the newer intent).
Returns null — leaving the state untouched — whenever the adoption does not commit:
- the request (or its page's load) rejected
- the document is a page of a different collection
- this state has not finished setting up its own collection yet
- the call was superseded by a newer navigation
const pages = getPaginationState(initialRequest);
// later, e.g. in a route model hook reacting to a ?page= param:
const adopted = await pages.adoptPage(store.request(query));
if (adopted === null) {
// not part of this collection — start a fresh pagination
}It is a stable reference, so it is safe to pass around as an "action" or "event" handler.
Parameters
request
Future<RT>
Returns
Promise<RT | null>
Implementation of
PagedPaginationState.adoptPageloadNext
loadNext: () => Promise<RT | null>;Extends the forward frontier by one page, appending it to data. Mirror of loadPrev.
In templates it is also available as the loadNext content feature (InfinitePaginationContentFeatures.loadNext) yielded by <Paginate />; the two are the same function.
<button {{on "click" pages.loadNext}}>Load more</button>Returns
Promise<RT | null>
Implementation of
InfinitePaginationState.loadNextloadPage
loadPage: (url: string) => Promise<RT | null>;Loads a specific page by its URL and makes it the activePage, requesting it first if it is not already loaded. This is the paged surface's navigation entry point, called by the numbered and relational links.
In templates it is also available as the loadPage content feature (PagedPaginationContentFeatures.loadPage) yielded by <Paginate />; the two are the same function.
It is a stable reference, so it is safe to pass around as an "action" or "event" handler. Returns the page's value, or null if it has none or the load fails.
On failure the page stays active and activePageRequest resolves to it, so a wrapping <Request> renders its error block. Calling again (for example clicking the page's link a second time) retries: the failed page is re-requested with a forced reload.
<EachLink @pages={{pages}}>
<:link as |link|>
<button {{on "click" (fn features.loadPage link.url)}}>{{link.text}}</button>
</:link>
</EachLink>Parameters
url
string
Returns
Promise<RT | null>
Implementation of
PagedPaginationState.loadPageloadPrev
loadPrev: () => Promise<RT | null>;Extends the backward frontier by one page, prepending it to data. The frontier advances only once the page has loaded, so previousRequest tracks the in-flight page meanwhile. Returns the loaded value, or null when there is no previous page or the load fails.
On failure the frontier stays put and previousRequest keeps resolving to the failed page, so a wrapping <Request> renders its error block. Calling again retries: the failed page is re-requested with a forced reload.
In templates it is also available as the loadPrev content feature (InfinitePaginationContentFeatures.loadPrev) yielded by <Paginate />; the two are the same function.
It is a stable reference, so it is safe to pass around as an "action" or "event" handler.
Returns
Promise<RT | null>
Implementation of
InfinitePaginationState.loadPrevactivePageRequest
Get Signature
get activePageRequest(): Future<RT> | null;The request for the activePage, for the paged surface to render. This is what a single-page view wraps in a <Request> to show the active page's loading, error, and content states:
<Paginate @request={{this.request}}>
<:content as |pages|>
<Request @request={{pages.activePageRequest}}>
<:content as |result|>
{{#each result.data as |item|}}...{{/each}}
</:content>
</Request>
</:content>
</Paginate>Returns
Future<RT> | null
Implementation of
PagedPaginationState.activePageRequestdata
Get Signature
get data(): Iterable<ContentItem<RT>>;The accumulated items across the loaded run, from the backward frontier to the forward frontier inclusive — the single set an infinite collection renders. Grows as loadNext/loadPrev extend the frontier. Scoped to this component's frontier (not the shared cache), so components paging the same collection to different extents each see only what they have scrolled through.
The flattened items of pages, as one contiguous iterable. For the items of every loaded page in the whole collection, see PaginationCache.data.
<Paginate @request={{this.request}} @mode="infinite">
<:content as |pages features|>
{{#each pages.data as |item|}}...{{/each}}
{{#if pages.hasNext}}
<button {{on "click" features.loadNext}}>Load more</button>
{{/if}}
</:content>
</Paginate>Returns
Iterable<ContentItem<RT>>
Implementation of
InfinitePaginationState.datahasNext
Get Signature
get hasNext(): boolean;Whether a page exists after the forward frontier — i.e. there is more to load going forward. Use to hide the trailing load-more sentinel at end-of-list:
{{#if pages.hasNext}}
<button {{on "click" features.loadNext}}>Load more</button>
{{/if}}Returns
boolean
Implementation of
InfinitePaginationState.hasNexthasPrevious
Get Signature
get hasPrevious(): boolean;Whether a page exists before the backward frontier.
Returns
boolean
Implementation of
InfinitePaginationState.hasPreviousnextRequest
Get Signature
get nextRequest(): Future<RT> | null;The request for the page just after the forward frontier, for the infinite surface. null until loadNext fires it (so a <Request> wrapping it renders its idle block), the in-flight Future while that page loads, then null again once the frontier advances onto it. Also null at end-of-list.
{{#if pages.hasNext}}
<Request @request={{pages.nextRequest}}>
<:idle><button {{on "click" features.loadNext}}>Load more</button></:idle>
<:loading><Spinner /></:loading>
</Request>
{{/if}}Returns
Future<RT> | null
Implementation of
InfinitePaginationState.nextRequestpages
Get Signature
get pages(): Iterable<Readonly<PageCache<RT, E>>>;The pages of the run this component is viewing, from the backward frontier to the forward frontier inclusive, in order. Part of the infinite surface: it is the same run as data, yielding the PageCache objects instead of their flattened items — use it when the UI needs per-page boundaries or request states.
Grows as loadNext/loadPrev extend the frontier. Scoped to this component's frontier (not the shared cache), so components paging the same collection to different extents each see only what they have scrolled through. For every page known to the whole collection, see PaginationCache.pages.
Returns
Iterable<Readonly<PageCache<RT, E>>>
Implementation of
InfinitePaginationState.pagespreviousRequest
Get Signature
get previousRequest(): Future<RT> | null;The request for the page just before the backward frontier. Mirror of nextRequest for loadPrev.
Returns
Future<RT> | null
Implementation of
InfinitePaginationState.previousRequesttotalPages
Get Signature
get totalPages(): number;The total number of pages in the collection, or 0 when it is unknown (for example a cursor-based collection that reports no total).
<p>Page {{pages.activePage.pageNumber}} of {{pages.totalPages}}</p>Returns
number