javascript - Angular 5 show "No data found" on ngIf empty results - Stack Overflow

I'm using Angular 5 and I'm building a list of items with some buttons that filter the list.

I'm using Angular 5 and I'm building a list of items with some buttons that filter the list. What I'm struggling to do is show a "No data found" kind of message when one of those filters hide every item of the list.

It's basically this:

The filter buttons

<div padding>
    <ion-segment [(ngModel)]="filter" (ionChange)="onFilterChange()">
        <ion-segment-button value="all">
            All
        </ion-segment-button>
        <ion-segment-button value="2">
            Pending
        </ion-segment-button>
        <ion-segment-button value="1">
            Confirmed
        </ion-segment-button>
    </ion-segment>
</div>

The list

<ion-list *ngFor="let r of (reservations | async)">
    <ion-card *ngIf="(filter == 'all' || filter == r.confirmed)">
        <ion-item>
            Item
        </ion-item>
    </ion-card>    
</ion-list>

Note: I'm using the async pipe because data es from Firebase Realtime Database.

So, all my items are in a state of pending (having confirmed: 2), so when I click on the Confirmed button, all the items on the list get hidden, which is perfect. But how can I show a "No data found" message instead of an empty list?

I've tried the else condition, but I'm getting multiple "No data found" messages (one for each hidden item):

<ion-list *ngFor="let r of (reservations | async)">
    <ion-card *ngIf="(filter == 'all' || filter == r.confirmed); else empty;">
        <ion-item>
            Item
        </ion-item>
    </ion-card>    
</ion-list>
<ng-template #empty>
    No data found...
</ng-template>

So what's the correct way of achieving this? Thanks.

I'm using Angular 5 and I'm building a list of items with some buttons that filter the list. What I'm struggling to do is show a "No data found" kind of message when one of those filters hide every item of the list.

It's basically this:

The filter buttons

<div padding>
    <ion-segment [(ngModel)]="filter" (ionChange)="onFilterChange()">
        <ion-segment-button value="all">
            All
        </ion-segment-button>
        <ion-segment-button value="2">
            Pending
        </ion-segment-button>
        <ion-segment-button value="1">
            Confirmed
        </ion-segment-button>
    </ion-segment>
</div>

The list

<ion-list *ngFor="let r of (reservations | async)">
    <ion-card *ngIf="(filter == 'all' || filter == r.confirmed)">
        <ion-item>
            Item
        </ion-item>
    </ion-card>    
</ion-list>

Note: I'm using the async pipe because data es from Firebase Realtime Database.

So, all my items are in a state of pending (having confirmed: 2), so when I click on the Confirmed button, all the items on the list get hidden, which is perfect. But how can I show a "No data found" message instead of an empty list?

I've tried the else condition, but I'm getting multiple "No data found" messages (one for each hidden item):

<ion-list *ngFor="let r of (reservations | async)">
    <ion-card *ngIf="(filter == 'all' || filter == r.confirmed); else empty;">
        <ion-item>
            Item
        </ion-item>
    </ion-card>    
</ion-list>
<ng-template #empty>
    No data found...
</ng-template>

So what's the correct way of achieving this? Thanks.

Share Improve this question asked Feb 13, 2018 at 13:34 fanafana 3737 silver badges19 bronze badges 7
  • <ion-card *ngIf="filter != 'all' && filter != r.confirmed"> <ion-item> No Data </ion-item> </ion-card> – mast3rd3mon Commented Feb 13, 2018 at 13:37
  • Try moving <ng-template #empty> inside of the ion-list – Boris Lobanov Commented Feb 13, 2018 at 13:37
  • @mast3rd3mon That way it gives me duplicated "No Data", one for each hidden list item... – fana Commented Feb 13, 2018 at 14:02
  • @BorisLobanov Yes, I've tried that but the result is the same... – fana Commented Feb 13, 2018 at 14:03
  • This is not a good use case for else. Just use <div *ngIf ="(reservations | async).filter(f)">None</div> – Aluan Haddad Commented Feb 13, 2018 at 14:17
 |  Show 2 more ments

2 Answers 2

Reset to default 3

IMO you shouldnt display the raw list of reservations. Instead, display the already filtered list:

ponent.html

<ion-segment [formControl]="status" (ionChange)="onFilterChange()">
    <ion-segment-button value="2">
        Pending
    </ion-segment-button>
    <ion-segment-button value="1">
        Confirmed
    </ion-segment-button>
</ion>

<div *ngIf="empty$ | async; else notEmpty">
   Nothing
</div>
<ng-template #notEmpty>
   <ion-list *ngFor="let reservation of reservations$ | async">
        <ion-card>
            <ion-item>
                Item
            </ion-item>
        </ion-card>    
    </ion-list>
</ng-template>

ponent.ts

import {bineLatest} from 'rxjs/observable/bineLatest';
import {FormControl} from '@angular/forms';

status= new FormControl;
reservations$: Observable<IReservation[]>;
empty$: Observable<boolean>;

constructor(){
   this.reservations$ = bineLatest(rawReservations$,this.status.valueChanges,this._applyFilter);
  this.empty$ = this.reservations$.map(reservations => reservations.length === 0);
}

private _applyFilter(reservations: IReservation[], status: number): IReservation[]{
  let result = reservations;
  //apply filter logic
  return result;
}

Try this approach and tell me if it works for you.

Component:

// control variable
  dataAvailable = false;

  onFilterChange(filterType: number) {
    // your code and logic

    // This is pretty ugly, make it prettier please...    

    // checking if exists at least 1 reservation with confirmed = 1 | 2 (depends on argument).
    this.dataAvailable = this.reservations.filter(res => res.confirmed === filterType).length > 0;
  }

Template:

<div *ngIf="dataAvailable; then printData else empty"></div>

<ng-template #printData>
  <ion-list *ngFor="let r of (reservations | async)">
      <ion-card>
          <ion-item>
              Item
          </ion-item>
      </ion-card>    
  </ion-list>
</ng-template>
<ng-template #empty>
    No data found...
</ng-template>

So, my idea is that first we check if it's worth to loop through the data in the template. We check this in the ponent, we see if it exists any reservation with the filtered values.

If it doesn't exist, we won't loop, we just display (no data). If it does exist though, we'll loop and print them...

Does it makes sense? Hope it helps you or at least points you to the right direction!

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745251392a4618697.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信