@void-snippets/angular
injectInfinite
Infinite scroll pagination with fetchNextPage() and hasNextPage Signal.
#What it does
Loads paginated results page-by-page on demand — "Load more" or infinite scroll. Each call to fetchNextPage() appends the next batch. The allItems signal flattens all pages automatically so you never write pages.flatMap(p => p.items) yourself.
#Signature
typescript
contactResource.injectInfinite(params?: MaybeSignal<VSQueryParams>): VSAngularInfiniteResult<Contact.Base>#Return values
| Field | Type | Description |
|---|---|---|
pages | Signal | All fetched pages — each has items and pagination. |
allItems | Signal | Flattened list across all pages — use this for rendering. |
hasNextPage | Signal | false when you've reached the last page. |
isFetchingNextPage | Signal | true while the next page is loading. |
isLoading | Signal | true on the very first fetch. |
isFetching | Signal | true during any network request. |
isError | Signal | true when a fetch failed. |
error | Signal | The error from the last failed fetch. |
fetchNextPage | () => void | Fetches the next page. No-op when hasNextPage() is false. |
#Example
typescript
@Component({
template: `
@if (feed.isLoading()) {
<app-spinner />
} @else {
@for (contact of feed.allItems(); track contact._id) {
<app-contact-card [contact]="contact" />
}
@if (feed.hasNextPage()) {
<button (click)="feed.fetchNextPage()" [disabled]="feed.isFetchingNextPage()">
{{ feed.isFetchingNextPage() ? 'Loading…' : 'Load more' }}
</button>
} @else if (feed.allItems().length > 0) {
<p>All {{ feed.allItems().length }} contacts loaded.</p>
}
}
`,
})
export class ContactsFeedComponent {
private contactResource = useContactResource();
feed = this.contactResource.injectInfinite({ limit: 15 });
}