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

2

6

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>
Icj answered 24/5, 2018 at 21:38 Comment(1)
ANSWER The Angular Material require paginator and sort as the variable name for the respective function. using a different variables would break the paginator and sort functionality.. Kinda weirdIcj
A
5

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

Abrasion answered 25/5, 2018 at 18:55 Comment(1)
instead of referring them as queryListArray[index], is there any way to identify each of them using id?... something like queryListArray.getPaginator(id2)?Moorhead
B
0

You can use it like this:

IN ts:

@ViewChild('MatPaginator1') paginator: MatPaginator;
@ViewChild('MatPaginator2') paginator2: MatPaginator;

@ViewChild('sorter1') sorter1: MatSort;
@ViewChild('sorter2') sorter2: MatSort;

IN html:

#MatPaginator1="matPaginator"
#MatPaginator2="matPaginator"

#sorter1="matSort"
#sorter2="matSort"
Blair answered 16/6, 2021 at 13:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.