Create a Table With Sorting Pagination and Filter Using Angular Material in Ionic

Angular Material table in Ionic — sorting, pagination, filter tutorial by Gyaando.com

Create a Table With Sorting Pagination and Filter Using Angular Material in Ionic is a common requirement for admin dashboards and data-driven mobile apps. In this tutorial you’ll learn how to set up an Ionic Angular project, add Angular Material components, and implement a responsive data table with sorting, pagination, and filtering.

Prerequisites

  • Node.js and npm installed (if not, check your previous post).
  • Ionic CLI installed (npm install -g @ionic/cli).
  • Basic knowledge of Angular and Ionic components.
  • Project created using Ionic Angular.

Step-by-step Implementation

Step-1: Firstly Install Nodejs

If you did not install Node.js yet, first install it (see your previous post for guidance).


Step-2: Create Ionic App & Add Angular Material

Open a command window and run the following commands:

ionic start devdacticMaterial blank
cd devdacticMaterial
ng add @angular/material

Step-3: app.module.ts

After installing Angular Material, go to app/app.module.ts and copy-paste this code:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouteReuseStrategy } from '@angular/router';
 
import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';
 
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
 
@NgModule({
  declarations: [AppComponent],
  entryComponents: [],
  imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule, BrowserAnimationsModule],
  providers: [
    StatusBar,
    SplashScreen,
    { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

Note: Keep this file unchanged unless you add other modules/components.


Step-4: material.module.ts

Create app/material.module.ts (or use your existing shared module) — import and export Angular Material modules here. The file content you shared appears to mirror app.module.ts — ensure the material.module.ts actually imports Material components like MatTableModule, MatPaginatorModule, MatSortModule, MatInputModule, etc. Example minimal structure (if you want to replace later):

import { NgModule } from '@angular/core';
import { MatTableModule } from '@angular/material/table';
import { MatPaginatorModule } from '@angular/material/paginator';
import { MatSortModule } from '@angular/material/sort';
import { MatInputModule } from '@angular/material/input';

@NgModule({
  imports: [MatTableModule, MatPaginatorModule, MatSortModule, MatInputModule],
  exports: [MatTableModule, MatPaginatorModule, MatSortModule, MatInputModule]
})
export class MaterialModule {}

Step-5: home.page.ts (Table logic)

Go to app/home/home.page.ts and paste this code (kept exactly as you provided, with a small syntax fix noted below):

import { Component, OnInit, ViewChild } from "@angular/core";
import { MatPaginator, MatTableDataSource, MatSort } from '@angular/material';
 
@Component({
  selector: "app-home",
  templateUrl: "home.page.html",
  styleUrls: ["home.page.scss"]
})
export class HomePage implements OnInit {
  displayedColumns: string[] = ['first_name', 'last_name', 'twitter'];
  dataSource = new MatTableDataSource<any>([
    {
      first_name: 'Saam',
      last_name: 'smith',
      twitter: 'max'
    },
    {
      first_name: 'denny',
      last_name: 'don',
      twitter: 'dom'
    },
    {
      first_name: 'mark',
      last_name: 'sam',
      twitter: 'sam'
    }
  ]);
 
  @ViewChild(MatPaginator) paginator: MatPaginator;
  @ViewChild(MatSort) sort: MatSort;
 
  ngOnInit() {
    this.dataSource.paginator = this.paginator;
    this.dataSource.sort = this.sort;
  }
}

Step-6: home.page.html (Table template)

Paste this code into app/home/home.page.html:

<table mat-table [dataSource]="dataSource" class="mat-elevation-z8" matSort>
 
    <ng-container matColumnDef="first_name">
      <th mat-header-cell *matHeaderCellDef> First Name </th>
      <td mat-cell *matCellDef="let user"> {{user.first_name}} </td>
    </ng-container>
 
    <ng-container matColumnDef="last_name">
      <th mat-header-cell *matHeaderCellDef> Last Name </th>
      <td mat-cell *matCellDef="let user"> {{user.last_name}} </td>
    </ng-container>
 
    <ng-container matColumnDef="twitter">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> Twitter </th>
      <td mat-cell *matCellDef="let user"> {{user.twitter}} </td>
    </ng-container>

<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

<mat-paginator [pageSizeOptions]="[1, 2, 5]" showFirstLastButtons></mat-paginator>

Add Filtering (optional)

To add a simple global filter input, add this to your home.page.html above the table:

<mat-form-field>
  <input matInput (keyup)="applyFilter($event.target.value)" placeholder="Filter">
</mat-form-field>

And in home.page.ts implement the method:

applyFilter(filterValue: string) {
  this.dataSource.filter = filterValue.trim().toLowerCase();
}

Tips & Best Practices

  • Import the correct Material modules (MatTableModule, MatSortModule, MatPaginatorModule, MatFormFieldModule, MatInputModule).
  • If @ViewChild isn’t available in ngOnInit due to timing, move the paginator/sort assignment to ngAfterViewInit.
  • Use unique identifiers for data rows when handling selection or row operations.
  • For large datasets, use server-side pagination and sorting.

Leave a Comment

Your email address will not be published. Required fields are marked *