I'm trying to make the Angular Material pager functional to a table where the data comes from a service. I have followed a couple of tutorials from the Angular Material documentation, but the pager is not working
Code from html component:
<div>
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8 table-left">
<ng-container [matColumnDef]="column" *ngFor="let column of displayedColumns">
<th id="head" mat-header-cell *matHeaderCellDef> {{column}} </th>
<ng-container *ngIf="column != 'cities'; else optionsTemplate">
<td mat-cell *matCellDef="let element"> {{element[column]}} </td>
</ng-container>
<ng-template #optionsTemplate>
<td mat-cell *matCellDef="let element" class="action-link">
<button mat-raised-button (click)="loadCity(element.idDepartment)">Cities</button>
</td>
</ng-template>
</ng-container>
<tr mat-header-row *matHeaderRowDef="columnsToDisplay"></tr>
<tr mat-row *matRowDef="let row; columns: columnsToDisplay;"></tr>
</table>
<table mat-table [dataSource]="dataSourceCity" class="mat-elevation-z8">
<ng-container [matColumnDef]="column" *ngFor="let column of displayedColumnsC">
<th id="head" mat-header-cell *matHeaderCellDef> {{column}} </th>
<td mat-cell *matCellDef="let element"> {{element[column]}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="columnsToDisplayC"></tr>
<tr mat-row *matRowDef="let row; columns: columnsToDisplayC;"></tr>
</table>
<mat-paginator [pageSizeOptions]="[5, 10, 20]" showFirstLastButtons></mat-paginator>
</div>
Code from ts component:
import { Component, OnInit, ViewChild} from '@angular/core';
import { MatPaginator } from '@angular/material/paginator';
import { MatTableDataSource } from '@angular/material/table';
import { DepartmentService } from '../../_service/department.service';
import { Department } from 'src/app/_model/department';
@Component({
selector: 'app-search',
templateUrl: './search.component.html',
styleUrls: ['./search.component.css'],
})
export class SearchComponent implements OnInit {
displayedColumns: string[] = ['idDepartment', 'name', 'cities'];
columnsToDisplay: string[] = this.displayedColumns.slice();
depList: Department[] = [];
dataSource = [];
displayedColumnsC: string[] = ['idCity', 'name'];
columnsToDisplayC: string[] = this.displayedColumnsC.slice();
cityList: any[] = [];
dataSourceCity = new MatTableDataSource(this.cityList);
@ViewChild(MatPaginator) paginator: MatPaginator;
constructor(private departService: DepartmentService) { }
ngOnInit(): void {
this.dataSourceCity.paginator = this.paginator;
this.depList = [];
this.departService.list().subscribe(data => {
data.forEach(element => {
this.depList.push({idDepartment: element.idDepartment, name: element.name});
});
this.dataSource = this.depList;
});
}
loadCity(idDepartment): void {
this.departService.listCities(idDepartament).subscribe(data => {
data.forEach(element => {
this.cityList.push({idCity: element.idCity, name: element.name});
});
this.dataSourceCity.data = this.cityList;
console.log(this.dataSourceCity);
});
this.dataSourceCity.data = [];
this.cityList = [];
}
}
The data is displayed correctly in the table, but the paginator does not work, it is as if the data source was not "detected" by the paginator.
You have to assign the paginator after the datasource is defined:
loadCity(idDepartment): void {
this.departService.listCities(idDepartament).subscribe((data) => {
data.forEach((element) => {
this.cityList.push({ idCity: element.idCity, name: element.name });
});
this.dataSourceCity.data = this.cityList;
this.dataSourceCity.paginator = this.paginator
console.log(this.dataSourceCity);
});
this.dataSourceCity.data = [];
this.cityList = [];
}