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

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?



Solution 1:[1]

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

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

Solution 2:[2]

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;

Solution 3:[3]

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;
      });

Solution 4:[4]

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

Solution 5:[5]

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>

Solution 6:[6]

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"

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Muhammad Bilal
Solution 3 San Jaisy
Solution 4 Azametzin
Solution 5 4nkitpatel
Solution 6 Mohammed Sameer