Reputation: 735
I am using this code
<mat-table #table [dataSource]="dataSource" matSort >
<ng-container matColumnDef="tache">
<mat-header-cell *matHeaderCellDef mat-sort-header> tâche </mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.tache}} </mat-cell>
</ng-container>
<ng-container matColumnDef="outil">
<mat-header-cell *matHeaderCellDef mat-sort-header> outil </mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.outil}} </mat-cell>
</ng-container> <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;" (click)="selection.toggle(row)">
</mat-row>
</mat-table>
So, how to show empty message "No Record found" in data table.
Upvotes: 73
Views: 159754
Reputation: 11
Just as PLPeeters said If you are using Angluar Material >= 10 or more, then you can show a message when no data matches the filter, by using the *matNoDataRow directive, which looks something like this :
<tr class="mat-row" *matNoDataRow>
<td class="mat-cell" [attr.colspan]="displayedColumns.length">
No data matching the filter.
</td>
</tr>
If you are using Angular Material <10 Then You can use the following code to show data after filtering, if no data is available you can show the row with the text :
<!-- No Data Found -->
<ng-container matColumnDef="noDataFound" >
<td mat-footer-cell *matFooterCellDef colspan="7" [hidden]="dataSource?.filteredData?.length!=0">
No records found
</td>
</ng-container>
Upvotes: 1
Reputation: 1122
Inside your table add this
<tr class="mat-row" *matNoDataRow>
<td class="mat-cell" colspan="9999">No Transactions yet!</td>
</tr>
Upvotes: 0
Reputation: 4241
With Angular Material 10 or above If you want to show a message when not data matches the filter, you can use the *matNoDataRow directive.
<tr class="mat-row" *matNoDataRow>
<td class="mat-cell" [attr.colspan]="displayedColumns.length">
No data matching the filter.
</td>
</tr>
Upvotes: 122
Reputation: 91
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>
Upvotes: 0
Reputation: 1104
My solution does not alter the footer, and shows the message inside of the actual table by using CSS and adding a box :before
the footer:
First some CSS:
td.no-content {
padding-top: 7rem;
}
td.no-content:before {
content: attr(data-empty-message);
position: absolute;
top: 0;
left: 0;
right: 0;
text-align: center;
padding: 3rem 0 3rem 0;
background-color: white;
}
Then add the no-content
class to the footer TD when nothing is showing:
<td mat-footer-cell *matFooterCellDef
[class.no-content]="dataSource.filteredData.length === 0"
data-empty-message="Nothing found..."
>
Upvotes: 0
Reputation: 414
Step #0
In ts
dataSource: any = new MatTableDataSource()
Step #1
<table [dataSource]="dataSource">
<ng-container matColumnDef="nodata">
<td mat-footer-row *matFooterCellDef [colSpan]="displayedColumns.length"
style="text-align: center;">No Data Available</td>
</ng-container>
<tr mat-footer-row
[hidden]="dataSource.data.length >0"
*matFooterRowDef="['nodata']">
</tr>
</table>
Upvotes: 5
Reputation: 3177
In your component-name.component.html
:
<div class="mat-elevation-z8">
<mat-table [dataSource]="listData" matSort>
<ng-container matColumnDef="fullName">
<mat-header-cell *matHeaderCellDef mat-sort-header>Full Name</mat-header-cell>
<mat-cell *matCellDef="let element">{{element.fullName}}</mat-cell>
</ng-container>
...
...
<ng-container matColumnDef="noData">
<mat-footer-cell *matFooterCellDef colspan="6">
No data.
</mat-footer-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
<mat-footer-row *matFooterRowDef="['noData']" [ngClass]="{'hide':!(listData!=null && listData.data.length==0)}"></mat-footer-row>
</mat-table>
<mat-paginator [pageSizeOptions]="[5, 10, 25, 100]" [pageSize]="5" showFirstLastButtons></mat-paginator>
</div>
In your style.scss
or component-name.component.scss
define .hide
class
.hide { display: none; }
and that's all :)
Upvotes: 5
Reputation: 9186
this worked for me:
<ng-container matColumnDef="noRecords">
<td mat-footer-cell *matFooterCellDef>
No records found
</td>
</ng-container>
<tr mat-footer-row *matFooterRowDef="!dataSource.filteredData.length ? ['noRecords'] : []" colspan="2"></tr>
Also note that it's possible you have to add a <td mat-footer-cell *matFooterCellDef></td>
for every row if you already use the footer.
Upvotes: 0
Reputation: 448
You can use HTML hidden attribute to achieve same thing
<tr [hidden]="dataSource.data.length > 0" mat-footer-row *matFooterRowDef="['noRecord']" ></tr>
Upvotes: 1
Reputation: 1966
If anyone uses filter
with dataSource
, you should watch for dataSource.filteredData.length
.
i.e.
if (this.dataSource.filteredData.length < 1) {
this.presentDialog();
}
or
<div class="container" *ngIf="dataSource.filteredData.length < 1">
// Your message here...
</div>
Upvotes: 2
Reputation: 623
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>
Upvotes: 1
Reputation: 1
For anyone having the option to do this in the Footer, I have been able to do this by doing following steps in Angular 6/7/8:
1) In your [ComponentName].component.html
<table mat-table [dataSource]="dataSourceTable">
<ng-container matColumnDef="columneName">
<th mat-header-cell *matHeaderCellDef> Name </th>
<td mat-cell *matCellDef="let element"> {{element.columnname}} </td>
<td mat-footer-cell *matFooterCellDef>
<!-- Display a download button in the footer when data is available-->
<button mat-raised-button color="primary"
*ngIf="dataSourceTable.data.length > 0">Download</button>
<!--Below code is displayed when there is no data-->
<a mat-button *ngIf="dataSourceTable.data.length === 0">No Data
Found</a>
</td>
</ng-container>
<!--Below Lines of code generates Header, Row and footer for your table -->
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true;"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;">
</tr>
<tr mat-footer-row *matFooterRowDef="displayedColumns; sticky: true"></tr>
</table>
Upvotes: 0
Reputation: 19329
In newer Angular versions don't forget datasource.data
if your datasource is of type MatTableDataSource
.
Example:
In the TypeScript file:
// ...
datasource = new MatTableDataSource<object>([]);
// ...
And in the HTML file:
<div *ngIf="datasource.data.length > 0">
<!--Show the table.-->
</div>
<div *ngIf="datasource.data.length === 0">
<!--Show table is empty message. -->
</div>
Upvotes: 3
Reputation: 2213
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 = []
Upvotes: 27
Reputation: 2470
There are two ways to show error message in html
1st method using If method
<div *ngIf="dataSource.length">
<mat-table #table [dataSource]="dataSource" matSort >
<ng-container matColumnDef="tache">
<mat-header-cell *matHeaderCellDef mat-sort-header> tâche </mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.tache}} </mat-cell>
</ng-container>
<ng-container matColumnDef="outil">
<mat-header-cell *matHeaderCellDef mat-sort-header> outil </mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.outil}} </mat-cell>
</ng-container> <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;" (click)="selection.toggle(row)">
</mat-row>
</mat-table>
</div>
<div *ngIf="!dataSource.length">
No Record found
</div>
2nd Method Using If else
<div *ngIf="dataSource.length; else noRecord">
<mat-table #table [dataSource]="dataSource" matSort >
<ng-container matColumnDef="tache">
<mat-header-cell *matHeaderCellDef mat-sort-header> tâche </mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.tache}} </mat-cell>
</ng-container>
<ng-container matColumnDef="outil">
<mat-header-cell *matHeaderCellDef mat-sort-header> outil </mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.outil}} </mat-cell>
</ng-container> <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;" (click)="selection.toggle(row)">
</mat-row>
</mat-table>
</div>
<ng-template #noRecord>
<div>
No Record found
</div>
</ng-template>
Upvotes: 10
Reputation: 338
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>
Upvotes: 23
Reputation: 11
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>
Upvotes: 0
Reputation: 89
<mat-footer-row *matFooterRowDef="['noData']" [ngClass]="{'hide':!(listData!=null && listData.filteredData.length==0)}"></mat-footer-row>
I was able to solve the problem by doing this.
hide
is a custom css
.hide{
display:none;
}
Upvotes: 8
Reputation: 189
If you console.log dataSource, you will see the following: dataSource example
It is not the dataSource itself that is the array, but dataSource.data. dataSource is actually a class that has a property data that contains what you pass into MatTableDataSource (https://github.com/angular/material2/blob/master/src/lib/table/table-data-source.ts) Therefore, this is what you should be using for your *ngIf statement.
<div *ngIf="dataSource.data.length === 0">
No Records Found!
</div>
Hope this helps!
Upvotes: 19
Reputation: 15313
You can simply use the *ngIf
directive to check if dataSource
is not empty.
<mat-table *ngIf="dataSource.length > 0" #table [dataSource]="dataSource" matSort >
<ng-container matColumnDef="tache">
<mat-header-cell *matHeaderCellDef mat-sort-header> tâche </mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.tache}} </mat-cell>
</ng-container>
<ng-container matColumnDef="outil">
<mat-header-cell *matHeaderCellDef mat-sort-header> outil </mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.outil}} </mat-cell>
</ng-container> <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;" (click)="selection.toggle(row)">
</mat-row>
</mat-table>
<p *ngIf="dataSource.length === 0">No records found</p>
Upvotes: 1