Reputation: 23
I was trying to use the mat-sort and mat-paginator on my Material table which does not seem to work. The Table does get the data in the dataSource.data and it is also shown in the mat-table, but the dataSource.sort and dataSource.paginator properties stay undefined. I have tried to assign the values to both the properties in both ngOnInit() and ngAfterViewInit() as suggested in the other similar questions like the one here: mat-sort not working on mat-table, but nothing seems to work. Below is the code for the same. The version of Angular Material is 8.2.3 and the version of Angular is 8.3.25. I'll be glad for any help. Thanks in advance :)
employees-list.component.ts
import { Component, OnInit, ViewChild, AfterViewInit } from '@angular/core';
import { RestApiService } from '../shared/rest-api.service';
import { MatTableDataSource, MatSort, MatPaginator } from '@angular/material'; // Service used for Snackbar, Dialog,
@Component({
selector: 'app-employees-list',
templateUrl: './employees-list.component.html',
styleUrls: ['./employees-list.component.scss']
})
export class EmployeesListComponent implements OnInit, AfterViewInit {
public Employee: any = [];
public dataSource: any;
@ViewChild(MatSort, { static: true }) sort: MatSort;
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
displayedColumns: string[] = ['id', 'name', 'email', 'phone', 'actions'];
constructor(public restApi: RestApiService) { }
ngOnInit() {
this.loadEmployees();
}
// Get employees list
loadEmployees() {
return this.restApi.getEmployees().subscribe((data: {}) => {
console.log(data);
this.Employee = data;
this.dataSource = new MatTableDataSource(this.Employee);
this.dataSource.sort = this.sort;
this.dataSource.paginator = this.paginator;
console.log(this.dataSource);
});
}
ngAfterViewInit() {
}
// Delete employee
deleteEmployee(id) {
if (window.confirm('Are you sure, you want to delete?')) {
this.restApi.deleteEmployee(id).subscribe(data => {
this.loadEmployees();
});
}
}
}
employees-list.component.html
<div *ngIf="Employee.length !== 0">
<span class="mat-headline">Employee List</span>
<table mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8" >
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef mat-sort-header> User ID </th>
<td mat-cell *matCellDef="let element"> {{element.id}} </td>
</ng-container>
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Name </th>
<td mat-cell *matCellDef="let element"> {{element.name}} </td>
</ng-container>
<ng-container matColumnDef="email">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Email </th>
<td mat-cell *matCellDef="let element"> {{element.email}} </td>
</ng-container>
<ng-container matColumnDef="phone">
<th mat-header-cell *matHeaderCellDef> Phone </th>
<td mat-cell *matCellDef="let element"> {{element.phone}} </td>
</ng-container>
<ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef> Actions </th>
<td mat-cell *matCellDef="let element">
<button mat-raised-button routerLink="/employee-edit/{{element.id}}" color="primary"
style="margin-right: 0.25rem;"><mat-icon>edit</mat-icon></button>
<button mat-raised-button (click)="deleteEmployee(element.id)" color="warn"><mat-icon>delete</mat-icon></button>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
<mat-paginator [pageSizeOptions]="[5,10,20]" showFirstLastButtons></mat-paginator>
</table>
</div>
Upvotes: 2
Views: 5982
Reputation: 151
Use setters to solve the problem
@ViewChild(MatSort, { static: false })
set sort(v: MatSort) {
this.dataSource.sort = v;
}
@ViewChild(MatPaginator, { static: false })
set paginator(v: MatPaginator) {
this.dataSource.paginator = v;
}
Upvotes: 3
Reputation: 830
The problem is when you render you component you have this
*ngIf="Employee.length !== 0
so right now you don't have anything in your view until your condition becomes true and in this time your
@ViewChild(MatSort, { static: true }) sort: MatSort;
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
is trying to catch the sort and paginator from the view but your view doesn't have anything because your condition in this time isn't true so If you try to remove your condition everything will work
Upvotes: 3