mat-paginator breaks when mat-table is inside of NgIf

13.7k Views Asked by At

I have an angular project that is using mat-table and mat-paginator for a certain view, the problem is the view has a grid view and table view with a toggle, the grid view is default and table is hidden using an NgIf when the grid view is active. If I set the default to the table view then pagination works fine unless I swap to grid view and back, if the default if set to grid it breaks when I swap to the table view. I'm guessing its because the table is hidden when this code runs:

this.sliceList = new MatTableDataSource<Slice>(result);
this.sliceList.paginator = this.paginator;

I tried console logging this.sliceList and sliceList.paginator is undefined when the grid view is defaulted so I assuming this is the issue. How Can I fix this?

7

There are 7 best solutions below

1
On BEST ANSWER

according to this thread,try use [hidden] instead of *ngIf.

<div [hidden]="condition">
  <mat-table [dataSource]="dataSource">
  ...
  </mat-table>
</div>
0
On

loaddata hinders the funtionality of the mat paginator due to which ng if does not works in this condition . instead of using *ngIf use [hidden] = "condition on which u want to hide"

0
On

Create in file.html the <div> with these IDs:

div id="dataFound" style="display:none;"
div id="dataNotFound" style="display:none;"

In file.ts

document.getElementById("dataFound").style.display = 'none';    /* ngIf = false     
document.getElementById("dataNotFound").style.display = 'inline'; /* ngIf = true
1
On

1st Solution

Move mat-paginator from inside *ngIf div to outside

2nd Solution

use static false while declaring MatPaginator or MatSort

@ViewChild(MatPaginator, {static: false}) paginator: MatPaginator;
@ViewChild(MatSort, {static: false}) sort: MatSort;
0
On

For me I was using like this
Code Before:

 <div *ngIf="tableData?.data.length > 0; else noData">
      <mat-table [dataSource]="tableData" class="table-margin-0">
            ........
      </mat-table>
      <mat-paginator
            [pageSizeOptions]="[6, 10, 25, 50, 100]"
            showFirstLastButtons
      ></mat-paginator>
 </div>

Now using like this,
by adding [hidden] in paginator outside the *ngIf that works for me

Here is the code that worked
Code after:

<div *ngIf="tableData?.data.length > 0; else noData">
      <mat-table [dataSource]="tableData" class="table-margin-0">
            ........
      </mat-table>
 </div>
<mat-paginator
      [hidden]="tableData?.data.length === 0"
      [pageSizeOptions]="[6, 10, 25, 50, 100]"
      showFirstLastButtons
 ></mat-paginator>
1
On

I had the same problem and after some research I was able to make it work using the @ViewChild annotation and a set function.

In my component.ts file:

  constructor(private cdRef: ChangeDetectorRef) { }

  private paginator: MatPaginator;
  /*
   We are using @ViewChild because of the ngIf with async pipe on the template
   When the data is emmited for the first time from the observable, we need to bind the
   pagination component with the datasource. This can be achieved with the code bellow.
  */
  @ViewChild(MatPaginator) set matPaginator(mp: MatPaginator) {
    if(mp) {
      this.paginator = mp;
      this.dataSource = new MatTableDataSource<any>(your_data);
      this.dataSource.paginator = this.paginator;
      this.cdRef.detectChanges();
     }
   }

and in my template file:

  // my observable with the async pipe
  <div *ngIf="raceList$ | async as races">
    <div class="mat-table-width">
      <table mat-table [dataSource]="dataSource">
      ...
      </table>
      <mat-paginator [pageSizeOptions]="[10, 20, 30]"
                      showFirstLastButtons
                      aria-label="select page of races">
      </mat-paginator>
    </div>
  </div>
0
On

This solve my problem in ANgular 10

Setting static to False does the trick.

@ViewChild(MatPaginator, {static: false}) paginator: MatPaginator;
  @ViewChild(MatSort, {static: false}) sort: MatSort;

    ngAfterViewInit() {
        setTimeout(() => {
          this.matTableConfig.dataSource = new MatTableDataSource(this.matTableConfig.dataSource);
          this.matTableConfig.dataSource.paginator = this.paginator;
          this.matTableConfig.dataSource.sort = this.sort;
      });