Multiple Mat-Paginator in a single page (Angular 5 Data Table)

Umer picture Umer · May 24, 2018 · Viewed 8.1k times · Source

I have two Angular Data Tables in a single page. I am fetching the data from a Web Server (Async). I have created a an independent component for this. My first table is correctly displayed and binded to the sort and paginator but the second one doesn't work. Although it shows the data but the paginator and sort does not work on the second table. Any thoughts what could be the issue?

My Component TS File:

displayedColumns = ['customerId', 'projectId'];
@Input() dataSource2 = new MatTableDataSource<ScheduledTest>();
private paginator: MatPaginator;
private sort: MatSort;

@ViewChild(MatPaginator) set matPaginator(mp: MatPaginator) {
this.paginator = mp;
this.dataSource2.paginator = this.paginator;
}

@ViewChild(MatSort) set matSort(mp: MatSort) {
this.sort = mp;
this.dataSource2.sort = this.sort;
}

ngOnInit() {
this.getAllCurrentTestCases();
}

getAllCurrentTestCases() {
this.isError = false;
this.isLoading = true;
this.httpService.getAllCurrentTestCases(this.userService.accountNumber, this.userService.authToken)
  .then((data: AutomatedTest[]) => {
    this.isLoading = false;
    this.dataSource2 = new MatTableDataSource<AutomatedTest>(data);
    this.dataSource.sort = this.sort;
  })
  .catch(error => {
    this.isError = true;
  });
}

Component HTML:

<mat-table #table [dataSource]="dataSource2" matSort>

<ng-container matColumnDef="customerId">
  <mat-header-cell *matHeaderCellDef mat-sort-header>
    <b> Customer ID </b>
  </mat-header-cell>
  <mat-cell *matCellDef="let element"> {{element.data.customerId | uppercase }} </mat-cell>
</ng-container>

<ng-container matColumnDef="projectId">
  <mat-header-cell *matHeaderCellDef mat-sort-header>
    <b> Project ID </b>
  </mat-header-cell>
  <mat-cell *matCellDef="let element"> {{element.data.projectId | uppercase}} </mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;" matRipple class="element-row" [cdkDetailRow]="row" [cdkDetailRowTpl]="tpl"
  (toggleChange)="onToggleChange($event)"></mat-row>
<!-- <mat-row *matRowDef="let row; columns: ['expandedDetail']; when: isExpansionDetailRow" [@detailExpand]="row.element == expandedElement ? 'expanded' : 'collapsed'"
    style="overflow: hidden">
  </mat-row> -->

My Rendering Page

<app-table-com></app-table-com>
<app-table-com></app-table-com>

Answer

Ravi Mashru picture Ravi Mashru · May 25, 2018

Instead of using @ViewChild(MatSort) use @ViewChildren(MatSort). This will give you a QueryList<MatSort> that contains both MatSort instances.

You can do the same to get both instances of MatPaginator.

More about ViewChildren and QueryList here: https://netbasal.com/understanding-viewchildren-contentchildren-and-querylist-in-angular-896b0c689f6e