@void-snippets/angular

injectList

Paginated list — Signal fields for items, pagination, and three loading states.

#What it does

Fetches a paginated list for the resource. Returns a plain object of Signal fields — no .subscribe() needed. Accepts either a plain params object or a Signal (see MaybeSignal).

#Signature

typescript
contactResource.injectList(params?: MaybeSignal<VSQueryParams>): VSAngularListResult<Contact.Base>

#Parameters

ParameterTypeDefaultDescription
paramsMaybeSignaldefaultParamsPage, limit, and any extra filters. Pass a Signal to make the query reactive.

#Return values

FieldTypeDescription
listSignalItems for the current page. Always an array — never undefined.
paginationSignalPage metadata — { page, limit, totalPages, totalDocuments }
isLoadingSignaltrue only on the first fetch with no cached data. Use for full-page skeletons.
isFetchingSignaltrue during any network request — including background refetches.
isRefetchingSignaltrue during a background refetch while data is already visible. Use for a subtle "Refreshing…" badge.
isErrorSignaltrue when the most recent fetch threw an error.
errorSignalThe error itself.
refetch() => voidManually re-fires this specific query.
invalidate() => voidMarks the whole resource cache as stale, triggering background refetch for every mounted list and get for this resource.

#Example

typescript
@Component({
  template: `
    @if (contacts.isLoading()) {
      <app-table-skeleton />
    } @else if (contacts.isError()) {
      <app-error-state [message]="contacts.error()?.message" (retry)="contacts.refetch()" />
    } @else {
      @if (contacts.isRefetching()) { <mat-progress-bar mode="indeterminate" /> }

      @for (contact of contacts.list(); track contact._id) {
        <app-contact-row [contact]="contact" />
      }

      <app-paginator
        [page]="contacts.pagination().page"
        [limit]="contacts.pagination().limit"
        [total]="contacts.pagination().totalDocuments"
        (change)="onPageChange($event)"
      />
    }
  `,
})
export class ContactsComponent {
  private contactResource = useContactResource();

  page  = signal(1);
  limit = signal(20);

  contacts = this.contactResource.injectList(
    computed(() => ({ page: this.page(), limit: this.limit() })),
  );

  onPageChange({ page, limit }: { page: number; limit: number }) {
    this.page.set(page);
    this.limit.set(limit);
  }
}