Search code examples
angulartypescriptpaginationmat-table

How do I get pagination to work with ngIf on Angular?


I've tried using setTimeout(), and I've even tried using [hidden] instead of ngIf. I have also tried putting the paginator outside of the element wrapped in the ngIf. I will update my question as I do more research, but if anyone can point me in the right direction, that would be great. Below is the HTML code:

    <div fxLayout="row" fxLayoutAlign="center" class="report-container">
    <mat-card fxFlex.lg="98" fxFlex.md="98" fxFlex.sm="98" fxFlex.xs="98" *ngIf="!loading">
    <div fxLayout="row" fxLayoutAlign="space-between none">
      <mat-form-field>
        <mat-label>Report Type</mat-label>
        <mat-select [value]="reportOptions[0].path">
          <mat-option *ngFor="let option of reportOptions" [value]="option.path" routerLink="{{ option.link }}">
            {{ option.path }}</mat-option
          >
        </mat-select>
      </mat-form-field>

      <mat-search-bar matInput (keyup)="applyFilter($event.target.value)"></mat-search-bar>
    </div>

    <mat-table [dataSource]="dataSource" matSort>
      <ng-container matColumnDef="column1">
        <th mat-header-cell *matHeaderCellDef mat-sort-header>Column1</th>
        <td mat-cell *matCellDef="let element">
          <div class="mat-conventions text-data">
            {{ element.column1 }}
          </div>
        </td>
      </ng-container>

      <ng-container matColumnDef="column2">
        <th mat-header-cell *matHeaderCellDef mat-sort-header>Column2</th>
        <td mat-cell *matCellDef="let element">
          <div class="mat-conventions text-data">
            {{ element.column2 }}
          </div>
        </td>
      </ng-container>

      <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
      <tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
    </mat-table>

    <mat-paginator [pageSizeOptions]="[10, 25, 50]" showFirstLastButtons></mat-paginator>
  </mat-card>

  <div fxFlex.lg="98" fxFlex.md="98" fxFlex.sm="98" fxFlex.xs="98" *ngIf="loading" fxFill>
    <div fxLayout="row" fxLayoutAlign="center center">
      <mat-spinner *ngIf="loading" class="spinner-loading"></mat-spinner>
    </div>
  </div>
</div>

And here is the typescript code with ngOnInit and ngAfterViewInit:

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

constructor(private apollo: Apollo) {}

ngOnInit() {
  this.dataSource = new MatTableDataSource(this.reportData());
}

ngAfterViewInit() {
  this.dataSource.sort = this.sort;
  this.dataSource.paginator = this.paginator
}

Solution

  • Try to set this.dataSource.paginator = this.paginator after this.loading = false and this.dataSource.data = data

    UPD: You need to change AfterContentChecked to AfterContentInit and add it:

     private paginator: MatPaginator;
      @ViewChild(MatPaginator, {static: false}) set matPaginator(mp: MatPaginator) {
        this.paginator = mp;
        this.dataSource.paginator = this.paginator;
      }
    

    Example: https://stackblitz.com/edit/angular-afp7wg