Injects
injectInfiniteRead
Bidirectional paginated data fetching with infinite scroll support using Signals
Bidirectional paginated data fetching with infinite scroll support. Returns Angular Signals for reactive state binding.
Basic Usage
@Component({
selector: "app-post-list",
template: `
@if (canFetchPrev()) {
<button (click)="fetchPrev()" [disabled]="fetchingPrev()">
Load Previous
</button>
}
@for (post of data(); track post.id) {
<app-post-card [post]="post" />
}
@if (canFetchNext()) {
<button (click)="fetchNext()" [disabled]="fetchingNext()">
Load More
</button>
}
`,
})
export class PostListComponent {
private posts = injectInfiniteRead(
(api) => api("posts/paginated").GET({ query: { page: 1 } }),
{
canFetchNext: ({ response }) => response?.meta.hasMore ?? false,
nextPageRequest: ({ response, request }) => ({
query: { ...request.query, page: (response?.meta.page ?? 0) + 1 },
}),
merger: (allResponses) => allResponses.flatMap((r) => r.items),
canFetchPrev: ({ response }) => (response?.meta.page ?? 1) > 1,
prevPageRequest: ({ response, request }) => ({
query: { ...request.query, page: (response?.meta.page ?? 2) - 1 },
}),
}
);
data = this.posts.data;
loading = this.posts.loading;
canFetchNext = this.posts.canFetchNext;
canFetchPrev = this.posts.canFetchPrev;
fetchNext = this.posts.fetchNext;
fetchPrev = this.posts.fetchPrev;
fetchingNext = this.posts.fetchingNext;
fetchingPrev = this.posts.fetchingPrev;
}Options
| Option | Type | Required | Description |
|---|---|---|---|
canFetchNext | (ctx) => boolean | Yes | Check if next page exists |
nextPageRequest | (ctx) => Partial<TRequest> | Yes | Build request for next page |
merger | (allResponses) => TItem[] | Yes | Merge all responses into items |
canFetchPrev | (ctx) => boolean | No | Check if previous page exists |
prevPageRequest | (ctx) => Partial<TRequest> | No | Build request for previous page |
enabled | boolean | Signal<bool> | No | Whether to fetch automatically |
Context Object
type Context<TData, TRequest> = {
response: TData | undefined;
allResponses: TData[];
request: TRequest;
};Returns
| Property | Type | Description |
|---|---|---|
data | Signal<TItem[] | undefined> | Merged items from all responses |
allResponses | Signal<TData[] | undefined> | Array of all raw responses |
loading | Signal<boolean> | True during initial load |
fetching | Signal<boolean> | True during any fetch |
fetchingNext | Signal<boolean> | True while fetching next page |
fetchingPrev | Signal<boolean> | True while fetching previous |
canFetchNext | Signal<boolean> | Whether next page exists |
canFetchPrev | Signal<boolean> | Whether previous page exists |
fetchNext | () => Promise<void> | Fetch the next page |
fetchPrev | () => Promise<void> | Fetch the previous page |
refetch | () => Promise<void> | Refetch all pages |
abort | () => void | Abort current request |
error | Signal<TError | undefined> | Error if request failed |
meta | Signal<object> | Plugin-provided metadata |