Michiel
Michiel

Reputation: 4260

Material table component throws error on destroy

I am upgrading an application to Angular 10. In one of my components I use a material table. In the Angular 9 application my html looks like this:

<table mat-table [dataSource]="tableData" matSort class="mat-elevation-z8">

it works fine there, but when I upgrade to Angular 10 (angular material and angular) I get an error saying:

core.js:4442 ERROR TypeError: Cannot read property 'elementRef' of
undefined
    at MatTable._applyNativeTableSections (table.ts:1098)
    at MatTable.ngOnInit (table.ts:471)

this error dissapears when I change my html to:

  <mat-table [dataSource]="tableData" matSort class="mat-elevation-z8">
    
    <ng-container matColumnDef="date">
      <mat-header-cell *matHeaderCellDef mat-sort-header="date"> Date </mat-header-cell>
      <mat-cell *matCellDef="let element">{{dateAndTime(element.date)}}</mat-cell>
    </ng-container>
    <ng-container matColumnDef="type">
      <mat-header-cell *matHeaderCellDef mat-sort-header="type"> Type </mat-header-cell>
      <mat-cell *matCellDef="let element"> {{element.type}} </mat-cell>
    </ng-container>

    <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
    <mat-row *matRowDef="let row; columns: displayedColumns" (click)="onRowClicked(row)" class="clickable-row">
    </mat-row>
  </mat-table>

the page renders ok, sorting works but when I navigate away from the page I get the error:

core.js:4442 ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'viewContainer' of undefined
TypeError: Cannot read property 'viewContainer' of undefined
    at MatTable.ngOnDestroy (table.ts:525)

Inspection of this error reveals that it throws in the ngOnDestroy function of the table.

// table.ts from angular material 10.2
ngOnDestroy() {
    this._rowOutlet.viewContainer.clear();
    this._noDataRowOutlet.viewContainer.clear();  // error occurs here!
    this._headerRowOutlet.viewContainer.clear();
    this._footerRowOutlet.viewContainer.clear();

    this._cachedRenderRowsMap.clear();

    this._onDestroy.next();
    this._onDestroy.complete();

    if (isDataSource(this.dataSource)) {
      this.dataSource.disconnect(this);
    }
  }

Apparently I have no _noDataRowOutlet, does this mean I have to define a no-data-row? (and a footer and header because of the next lines of code) Or can i keep my template clean and avoid this error in somehow?

Upvotes: 2

Views: 732

Answers (1)

TomRaaff
TomRaaff

Reputation: 83

Updating to Angular 11 did not help for us. We got the same error, saying the _noDataRowOutlet was undefined. In our case, the problem arose because we overrode the CdkTable template and did not add the noDataRowOutlet directive. Adding this solved our problem:

<ng-container noDataRowOutlet></ng-container>

Upvotes: 1

Related Questions