I have 2 components. Both have mat-table and paginators and pagination is working for one component and not working for the other component though the code is similar. Below
I am quite a beginner in angular and typescript, but after having the same problem (except, that for me sorting didn't work either), what helped was creating a function 'refreshDataScource()
' and having it called from ngAfterViewInit()
as well as after each time the server responds with new data. In this function I simply refresh the dataSource
with the paginator and the sort. Like this:
refreshDataSource() {
this.dataSource = new MatTableDataSource(myDataArray);
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
}
It fixed the paginator and the sort. Everything works now perfectly. However I am not sure if it is just a workaround or a real fix.
Using setTimeOut() will solve the issue temporarily, however, this will again fail to work if you are pushing a huge load of Data [say 1000 rows] into MatDataSource.
we've found that the MatTable loads very slowly if a large data set is set before you set the data-source paginator.
ngOninit(){
// initialize dataSource here
}
ngAfterViewInit() {
this.dataSource.sort = this.sort;
this.dataSource.paginator = this.paginator;
/* now it's okay to set large data source... */
this.dataSource.data = [GetLargeDataSet];}
So, initialize the data-Source at first place and set the properties like "Paginator" or "Sort" before pushing the data into the source into the "Data" property.
Using setTimeout() is only a viable solution when you know how much time it will take to load the table. My problem was I using an *ngIf on the table (with !isLoading):
this.dataSource = new MatTableDataSource(this.rawData);
this.initPaginator();
this.isLoading = false;
The fix was setting my isLoading variable to false only after change detections and initializing the paginator:
this.dataSource = new MatTableDataSource(this.rawData);
this.isLoading = false;
this.cdr.detectChanges();
this.initPaginator();
So it loads the data -> shows the table -> detects changes -> inits paginator. I hope this helps anyone!
This is because of this.paginator is undefined at the time it going to assign to this.dataSource.paginator.
if you using static data this will work
@ViewChild(MatPaginator, {static: false}) paginator: MatPaginator; // For pagination
@ViewChild(MatSort, {static: false}) sort: MatSort; // For Sort
ngOnInit(): void {
this.dataSource.data = this.dataList; // Data list is data array
}
ngAfterViewInit(): void {
this.dataSource.paginator = this.paginator; // For pagination
this.dataSource.sort = this.sort; // For sort
}
if you using dynamic data (Data from API) this will work
For Pagination
@ViewChild(MatPaginator, {static: false})
set paginator(value: MatPaginator) {
if (this.dataSource){
this.dataSource.paginator = value;
}
}
For Sort
@ViewChild(MatSort, {static: false})
set sort(value: MatSort) {
if (this.dataSource){
this.dataSource.sort = value;
}
}
As a side note im using Angular 9 at the movement.
private paginator: MatPaginator;
private sort: MatSort;
@ViewChild(MatSort) set matSort(ms: MatSort) {
this.sort = ms;
this.setDataSourceAttributes();
}
@ViewChild(MatPaginator) set matPaginator(mp: MatPaginator) {
this.paginator = mp;
this.setDataSourceAttributes();
}
setDataSourceAttributes() {
if(this.dataSource !== undefined){
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
}
}
For me it was just add the property MatPaginator.length.
<mat-paginator [length]="Elements.length"
[pageSizeOptions]="[5, 10, 25, 100]">
</mat-paginator>