Components: if datasource is empty, how to display table rows like "No record found"

Created on 27 Nov 2017  路  15Comments  路  Source: angular/components

Bug, feature request, or proposal:

Bug

What is the expected behavior?

Need to display "No record found", if no records available

P4 materiatable

Most helpful comment

Hi @andrewseguin, I would also like to know how to achieve this basic feature using the MatTable, and hiding the table if there is no data is not only not answering the question but is a terrible suggestion from a UX perspective.

If this basic feature is not achievable then consider this a feature request.

All 15 comments

Use an ngIf on your table if there is no data

In the future: Please refer all troubleshooting questions to our community at StackOverflow, Angular Material mailing lists, Gitter, etc. We try to keep our issues here only open for bugs and feature requests.

Hi @andrewseguin, I would also like to know how to achieve this basic feature using the MatTable, and hiding the table if there is no data is not only not answering the question but is a terrible suggestion from a UX perspective.

If this basic feature is not achievable then consider this a feature request.

Don't we still have any solution for this?

Nothing? Really?

I guess the above only works if you're not using OnPush strategy. We've got 4 separate elements on the page:

<filters>
<table>
<no rows found>
<load more button>

Having alsorts of CD issues with ApolloAngular pulling in stuff. It just doesn't trigger CD and I can't subscribe to dataSource.data because it's literally returning a BehaviorSubject.value which throws away the benefits of using observables in the first place

Reading CDK Table code I can see that the component bypasses this problem by running the connect() and listening to that BehaviorSubject: https://github.com/angular/material2/blob/master/src/cdk/table/table.ts#L804

Which is where I placed logic for subscribing for more but seems it'll get called multiple times as I'll need to subscribe to changes as well just to update my own view

Paginator gets away with it by being passed directly to the DataSource class to be managed there

TL;DR - You can't just *ngIf things cause there's nothing for checking change detection. You'll have to create a custom data source and pass references to other components to force them to update OR make it emit a whole new array ref each time and pass it into a component to trigger OnPush

Rather than using the data property of the data source, you can use the connect stream which is what the table uses to know what to render. By applying the async pipe, you automatically gain the benefits of automatic change detection.

Here's quick prototype of what this looks like:
https://stackblitz.com/edit/angular-uymjz7-aqxffs?file=app/table-pagination-example.ts

@andrewseguin your solution doesn't work with footer situation.
i think mat-table should give a template interface to let developer implement the no data view.

Hm that's true, good catch. I'll re-open and we can reconsider this case

also how about an option to show the load-more icon for infinite scrolling tables? right now I have hacked the footer implementation to achieve this.. but a nicer way to achieve this would be beneficial. and this should be supported at the cdk-table level..

My workaround is to add ng-container with an *ngIf below the table:

<table [dataSource]="dataSource">
...
</table>
<ng-container *ngIf="dataSource.data.length > 0">
    <p>There is no data for this filter</p>
</ng-container>

I'm still very new to these DataSource-based tables, but it appears that not all datasource objects have a "data" property. Checking data.length property of the datasource only seems to work for local data sources. I cannot figure out how to ask for the data length in the case where a data source wraps a service to call a backend REST endpoint each time. In my case the datasource class is defined as "MyDataSource extends DataSource<MyDataModel>".

For the record, I've released a Reactive DataSource to handle all this kind of stuff:
https://medium.com/@matheo/reactive-datasource-for-angular-1d869b0155f6

@matheo when empty data, the header should keep show.
something like this.

image

or like this

image

I mapped my api in some array variable department and then try *ngIf ="department.length >0 is showing table and *ngIf ="department.length == 0" then showing no data found this is working for me but getting error in console length of undefined.

I guess this can be closed after the implementation of *matNoDataRow in v10 (PR https://github.com/angular/components/pull/18041).

We can do it like this now:

<tr class="mat-row" *matNoDataRow>
  <td class="mat-cell">No data matching the filter</td>
</tr>
Was this page helpful?
0 / 5 - 0 ratings

Related issues

shlomiassaf picture shlomiassaf  路  3Comments

Miiekeee picture Miiekeee  路  3Comments

RoxKilly picture RoxKilly  路  3Comments

vitaly-t picture vitaly-t  路  3Comments

xtianus79 picture xtianus79  路  3Comments