PagedList - spinningideas/resources GitHub Wiki

Javascript Implementation

The JavaScript/TypeScript implementation mirrors the C# PagedList<T> pattern. It uses the Pagination class and ApiResponsePaged<T> types defined in Paging-Data.

Pagination Class

export class Pagination {
  public totalResults: number = 0;
  public totalPages: number = 0;
  public pageSize: number = 20;
  public pageNumber: number = 1;
  public resultsExist: boolean = false;
  public hasPreviousPage: boolean = false;
  public hasNextPage: boolean = false;

  constructor(pageSize: number, pageNumber: number, total: number) {
    this.pageSize = pageSize;
    this.pageNumber = pageNumber;
    this.totalResults = total;
    this.resultsExist = total > 0;
    this.totalPages = Math.ceil(this.totalResults / this.pageSize);
    this.hasPreviousPage = pageNumber > 1;
    this.hasNextPage =
      this.pageSize === 1
        ? this.totalResults > this.pageSize
        : this.totalPages > pageNumber;
  }
}

PagedList Class

import { Pagination } from "./pagination";
import type ApiResponsePaged from "./types";

export class PagedList<T> {
  public items: T[];
  public pagination: Pagination;

  constructor(items: T[], pageSize: number, pageNumber: number, total: number) {
    this.items = items;
    this.pagination = new Pagination(pageSize, pageNumber, total);
  }

  get currentPage(): number {
    return this.pagination.pageNumber;
  }

  get totalPages(): number {
    return this.pagination.totalPages;
  }

  get totalResults(): number {
    return this.pagination.totalResults;
  }

  get hasNextPage(): boolean {
    return this.pagination.hasNextPage;
  }

  get hasPreviousPage(): boolean {
    return this.pagination.hasPreviousPage;
  }

  /** Build a PagedList directly from a typed API response */
  static fromResponse<T>(response: ApiResponsePaged<T[]>): PagedList<T> {
    const p = response.pagination;
    if (!p) {
      throw new Error("Response does not contain pagination metadata");
    }
    return new PagedList<T>(
      response.data ?? [],
      p.pageSize,
      p.pageNumber,
      p.totalResults,
    );
  }

  /** Slice an in-memory array into a PagedList (equivalent to C# ToPagedList) */
  static fromArray<T>(
    source: T[],
    pageNumber: number,
    pageSize: number,
  ): PagedList<T> {
    const total = source.length;
    const items = source.slice((pageNumber - 1) * pageSize, pageNumber * pageSize);
    return new PagedList<T>(items, pageSize, pageNumber, total);
  }
}

Usage Example

import { PagedList } from "./pagedList";

// --- From an API response ---
const response = await fetch("/api/products/search", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ searchTerm: "widget", pageNumber: 1, pageSize: 10 }),
}).then((r) => r.json());

const page = PagedList.fromResponse<Product>(response);

console.log(page.items);           // Product[] for the current page
console.log(page.currentPage);     // 1
console.log(page.totalPages);      // 5
console.log(page.hasNextPage);     // true
console.log(page.hasPreviousPage); // false

// --- From an in-memory array ---
const all = [/* ...47 products... */];
const page2 = PagedList.fromArray(all, 2, 10);

console.log(page2.items.length);   // 10
console.log(page2.currentPage);    // 2
console.log(page2.hasNextPage);    // true

C# Implementation

public class PagedList<T> : List<T>
{
	public int CurrentPage { get; private set; }
	public int TotalPages { get; private set; }
	public int PageSize { get; private set; }
	public int TotalCount { get; private set; }

	public bool HasPrevious => CurrentPage > 1;
	public bool HasNext => CurrentPage < TotalPages;

	public PagedList(List<T> items, int count, int pageNumber, int pageSize)
	{
		TotalCount = count;
		PageSize = pageSize;
		CurrentPage = pageNumber;
		TotalPages = (int)Math.Ceiling(count / (double)pageSize);

		AddRange(items);
	}

	public static PagedList<T> ToPagedList(IQueryable<T> source, int pageNumber, int pageSize)
	{
		var count = source.Count();
		var items = source.Skip((pageNumber - 1) * pageSize).Take(pageSize).ToList();

		return new PagedList<T>(items, count, pageNumber, pageSize);
	}
}
⚠️ **GitHub.com Fallback** ⚠️