Complete Guide to Angular Material Paginator: From Basic Configuration to Dynamic Data Updates

Nov 24, 2025 · Programming · 8 views · 7.8

Keywords: Angular Material | Paginator | Data Pagination | PageEvent | Server-Side Pagination

Abstract: This article provides an in-depth exploration of properly implementing the Material Design paginator component in Angular applications. Through detailed analysis of best practices, we demonstrate how to configure paginator properties, handle page events, implement server-side data fetching, and compare alternative client-side pagination approaches. The article includes complete code examples and step-by-step explanations to help developers master the full implementation workflow, with special focus on event binding, data update mechanisms, and solutions to common issues.

Basic Paginator Configuration and Property Binding

In Angular Material, the paginator component provides robust data pagination capabilities. First, import the necessary dependencies in your module:

import { MatPaginatorModule } from '@angular/material/paginator';

Then configure the basic properties in your component template:

<mat-paginator [length]="totalRecords"
              [pageSize]="pageSize"
              [pageSizeOptions]="[5, 10, 25, 100]"
              (page)="handlePageChange($event)">
</mat-paginator>

Define these properties in the corresponding component class:

export class DataTableComponent implements OnInit {
  totalRecords = 100;
  pageSize = 10;
  pageSizeOptions = [5, 10, 25, 100];
  
  // Other properties and methods
}

Page Event Handling and Data Updates

The core functionality of the paginator lies in handling page change events. When users switch pages or change page size, the page event is triggered, carrying a PageEvent object:

interface PageEvent {
  pageIndex: number;
  pageSize: number;
  length: number;
  previousPageIndex?: number;
}

Define the event handling method in your component:

handlePageChange(event: PageEvent): void {
  this.currentPage = event.pageIndex;
  this.pageSize = event.pageSize;
  this.loadData();
}

Server-Side Data Fetching Implementation

For large datasets, server-side pagination is recommended. Call the service to fetch data within the event handling method:

loadData(): void {
  const params = {
    page: this.currentPage,
    size: this.pageSize
  };
  
  this.dataService.fetchData(params).subscribe({
    next: (response) => {
      this.dataSource = response.data;
      this.totalRecords = response.total;
    },
    error: (error) => {
      console.error('Data loading failed:', error);
    }
  });
}

Alternative Client-Side Pagination Approach

For smaller datasets, client-side pagination can be used. Display current page data by calculating slice indices:

updateDisplayedData(): void {
  const startIndex = this.currentPage * this.pageSize;
  const endIndex = startIndex + this.pageSize;
  this.displayedData = this.allData.slice(startIndex, endIndex);
}

Using Paginator Methods

Although the paginator provides methods like nextPage() and previousPage(), event handling is typically more straightforward in practical applications. These methods are mainly used for programmatic control:

@ViewChild(MatPaginator) paginator!: MatPaginator;

navigateToNextPage(): void {
  if (this.paginator.hasNextPage()) {
    this.paginator.nextPage();
  }
}

navigateToPreviousPage(): void {
  if (this.paginator.hasPreviousPage()) {
    this.paginator.previousPage();
  }
}

Complete Implementation Example

Here's a complete example of data table integration with paginator:

@Component({
  selector: 'app-data-table',
  template: `
    <table mat-table [dataSource]="displayedData">
      <!-- Column definitions -->
    </table>
    <mat-paginator [length]="totalRecords"
                   [pageSize]="pageSize"
                   [pageSizeOptions]="[5, 10, 25]"
                   (page)="handlePageChange($event)">
    </mat-paginator>
  `
})
export class DataTableComponent implements OnInit {
  displayedData: any[] = [];
  totalRecords = 0;
  pageSize = 10;
  currentPage = 0;

  ngOnInit(): void {
    this.loadData();
  }

  handlePageChange(event: PageEvent): void {
    this.currentPage = event.pageIndex;
    this.pageSize = event.pageSize;
    this.loadData();
  }

  private loadData(): void {
    this.dataService.getPaginatedData({
      page: this.currentPage,
      size: this.pageSize
    }).subscribe({
      next: (response) => {
        this.displayedData = response.data;
        this.totalRecords = response.total;
      },
      error: (error) => console.error('Error:', error)
    });
  }
}

Common Issues and Solutions

In actual development, you might encounter issues where the paginator doesn't update the view. Ensure that all relevant properties are correctly set after data updates. If using MatTableDataSource, make sure the paginator instance is properly bound:

this.dataSource = new MatTableDataSource(data);
this.dataSource.paginator = this.paginator;

With the above implementation, you can build fully functional, user-friendly pagination features that handle both local and remote data effectively.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.