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
@ViewChildisn’t available inngOnInitdue to timing, move the paginator/sort assignment tongAfterViewInit. - Use unique identifiers for data rows when handling selection or row operations.
- For large datasets, use server-side pagination and sorting.



