I am using this code
I was getting a runtime error "Cannot read property 'length' of undefined" if the array was null. Solved it by first checking the null value, and if true it does not proceed to the length test, thus not causing the error. i.e.
<tr *ngFor="let category of _projectCategories">
<td>
{{ category.name }}
</td>
<td>
{{ category.description }}
</td>
<td>
{{ category.group }}
</td>
<td>
<i class="nc-icon" [class.nc-check-2]="category.active"
[class.nc-simple-remove]="!category.active"></i>
</td>
</tr>
<tr *ngIf="(_projectCategories==null) || (_projectCategories.length == 0)">
<td colspan="2">
Project currently has no categories.
</td>
</tr>
In .ts file
if (this.dataSource.length == 0) {
this.noDataMessage = true;
} else {
this.noDataMessage = false;
}
In .html file
<div *ngIf="noDataMessage">
<p>{{ 'label.DataNotAvailable' | translate }}</p>
</div>
You can add a condition on your dataSource directly without having to access the data or its length:
<div *ngIf="!yourDataSource" class="alert alert-primary" role="alert">No data </div>
You can put it in the footer row this way:
Column definition:
<ng-container matColumnDef="noRecord">
<td mat-footer-cell *matFooterCellDef>No records found.</td>
</ng-container>
Footer row definition:
<ng-template [ngIf]="dataSource.data.length === 0">
<tr mat-footer-row *matFooterRowDef="['noRecord']"></tr>
</ng-template>
It's like bugs is saying, you can just use *ngIf
. Compare these two tables here:
https://stackblitz.com/edit/angular-w9ckf8
<mat-toolbar color="primary">My empty table</mat-toolbar>
<mat-table #table [dataSource]="dataSourceEmpty" matSort *ngIf="dataSourceEmpty.length > 0">
<ng-container matColumnDef="Name">
<mat-header-cell *matHeaderCellDef mat-sort-header>Name </mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.name}} </mat-cell>
</ng-container>
<ng-container matColumnDef="Age">
<mat-header-cell *matHeaderCellDef mat-sort-header>Age </mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.age}} </mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;" (click)="row.toggle(row)">
</mat-row>
</mat-table>
<div *ngIf="dataSourceEmpty.length === 0">No records found</div>
<hr>
<mat-toolbar color="primary">My full table</mat-toolbar>
<mat-table #table [dataSource]="dataSource" matSort *ngIf="dataSource.length > 0">
<ng-container matColumnDef="Name">
<mat-header-cell *matHeaderCellDef mat-sort-header>Name </mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.name}} </mat-cell>
</ng-container>
<ng-container matColumnDef="Age">
<mat-header-cell *matHeaderCellDef mat-sort-header>Age </mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.age}} </mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;" (click)="row.toggle(row)">
</mat-row>
</mat-table>
<div *ngIf="dataSource.length === 0">No data</div>
TS with data:
displayedColumns = ['Name', 'Age']
dataSource = [{name:'Sara',age:17}, {name: 'John', age: 20}]
dataSourceEmpty = []
You can use HTML hidden attribute to achieve same thing
<tr [hidden]="dataSource.data.length > 0" mat-footer-row *matFooterRowDef="['noRecord']" ></tr>