Search code examples
angularsortingangular-material-tablemat-pagination

Angular how to sort table data based on page using paginator and matsort


So I have been working on this project where I had to sort the table data per pagination. For example I have 200 data on my table, and per page it is showing 20 data 1-20. If I click the sort icon, it should sort 1-20 to 20-1, but the code that I have would sort it from 1-20 to 200-180. I dont know what method to use, I think this.dataSource.sortData might be one solution but I dont know how to implement it. Here is my code


export class footballerComponent implements OnInit{

   data = [ {"name": "Cristiano Ronaldo", "age" : "37"}
            {"name": "Neymar", "age" : "29"}
            {"name": "Messi", "age" : "34"}
            {"name": "KDB", "age" : "31"}
            {"name": "Aguero", "age" : "29"}
            {"name": "Suarez", "age" : "32"}
            {"name": "Mbappe", "age" : "17"}]

   displayColumns: string[] = Objects.keys(this.data[0]);
   dataSource = new MatTableDataSource(this.data);

   @ViewChild(MatPaginator) paginator: MatPaginator;
   @ViewChild(MatSort, {static:false}) sort: MatSort;

   ngAfterViewInt(){
     this.dataSource.sort = this.sort;
     this.dataSource.paginator = this.paginator;
   }

   constructor(){}

   ngOnInit():void{
   }
}

And this is my html code:


<mat-paginator #paginator [pageSize]="3" [pageSizeOptions]="[2,3,4,5]" showFirstLastButtons></mat-paginator>

<table mat-table [dataSource]="dataSource matSort class="mat-elevation-z8">
 <ng-container [matColumnDef]="column" *ngFor="let column of dispalyedColumns">
   <th mat-header-cell *matHeaderCellDef mat-sort-header> {{ column }}</th>
   <td mat-cell *matCellDef="let emp"> {{ emp[column] }}</td>
 </ng-container>

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


Solution

  • The filtering / sorting / paging logic is built into MatTableDataSource. Since the "normal" (i.e. by FAR most common) case would be to to first filter, then sort, and then page the data, this is what the MatTableDataSource does. This is baked into internal methods, where different observables are chained and merged to create the result set.

    Since you want to first filter, then page and THEN sort the data (which, have in mind, seems counter-intuitive from the UX perspective), you will have to write your own custom implementation of DataSource<T>. You can find the base abstract class here.

    You can base your implementation on the MatTableDataSource, which can be found here. Most of the magic happens in the _updateChangeSubscription method.