AOUADI Slim
AOUADI Slim

Reputation: 457

Angular 6 how to check if my pipe filter returns an empty array

i have a list of dinosaures that i iterate throught it and then i added a search input to filter the list by login property like this

<input type="text" class="recherche" [(ngModel)]="loginToSearch" placeholder="Entrez votre recherche ici...">

    <li *ngFor="let dinosaure of dinosauresList | filter: login : loginToSearch" class="list-group-item text-left">
      <div>
        <img class="img-thumbnail" src="{{ dinosaure.profileImage}}">
        <label class="name">
          {{dinosaure.login}}<br>
        </label>
      </div>
      <div class="btn-plus">
        <label class="pull-right">
          <a class="btn btn-success btn-xs glyphicon glyphicon-plus" 
                 (click)="onClickAddFriend(dinosaure)"
            title="View"></a>
        </label>
      </div>

    </li>

but i want to add a condition to display a message or form when there are no results returned by the filter , i tried many solutions that i found but none of them worked for me.

this is my filter :

   @Pipe({
     name: 'filter'
  })
export class FilterPipe implements PipeTransform {

      transform(value: any, args: any, loginToSearch: string): any {
        if (!value) {

         return null;
         }
      if (!args && !loginToSearch) {
              return value;
             }
         loginToSearch = loginToSearch.toString().toLowerCase();
             return value.filter(data => {
           return data.login.includes(loginToSearch);
                 });

                }

             }

Upvotes: 0

Views: 1668

Answers (2)

Hareen Udayanath
Hareen Udayanath

Reputation: 11

You can do it using two ng-containers

The answer:

<input type="text" class="recherche" [(ngModel)]="loginToSearch" placeholder="Entrez votre recherche ici...">

<ng-container *ngIf="dinosauresList | filter: login : loginToSearch;let filteredDinosauresList">
  <ng-container *ngIf="filteredDinosauresList.length>0;else noResultsView">
    <li *ngFor="let dinosaure of filteredDinosauresList" class="list-group-item text-left">
      <div>
        <img class="img-thumbnail" src="{{ dinosaure.profileImage}}">
        <label class="name">
          {{dinosaure.login}}<br>
        </label>
      </div>
      <div class="btn-plus">
        <label class="pull-right">
          <a class="btn btn-success btn-xs glyphicon glyphicon-plus"
             (click)="onClickAddFriend(dinosaure)"
             title="View"></a>
        </label>
      </div>

    </li>
  </ng-container>
</ng-container>

<div #noResultsView>Your error message for no results</div>
  • Inside the first ng-container, we filter and assign the filtered list into a local template variable using let.

  • Then in the second ng-container we check the length of that filtered list to show the empty results view or not.

  • We can use the same local template variable inside the *ngFor in order to prevent multiple filter operations

Upvotes: 1

BELLIL
BELLIL

Reputation: 765

I would recommend you to change the manner of work,

you can add an ng on (ngModelChange) to your front

so your input will be like this

<input type="text" class="recherche" [(ngModel)]="loginToSearch" placeholder="Entrez votre recherche ici..."  (ngModelChange)="onFilterValueChange()" >

and then in your component you declare a temporary list and you search your value

temporaryList = [];
onFilterValueChange(){
        if(this.loginToSearch){
         this.temporaryList = this.dinosauresList.filter(data => data.login.includes(this.loginToSearch));} 
         else {  this.temporaryList  = this.dinosauresList;
        }}

and then in your html you can do

<div *ngIf="temporaryList  === 0;else results"> Your error message  </div>

<ng-template #results>
    <li *ngFor="let dinosaure of temporaryList " class="list-group-item text-left">
      <div>
        <img class="img-thumbnail" src="{{ dinosaure.profileImage}}">
        <label class="name">
          {{dinosaure.login}}<br>
        </label>
      </div>
      <div class="btn-plus">
        <label class="pull-right">
          <a class="btn btn-success btn-xs glyphicon glyphicon-plus" 
                 (click)="onClickAddFriend(dinosaure)"
            title="View"></a>
        </label>
      </div>

    </li>

</ng-template>

If you insist to work with your pipe, you'll have to create a service that contains an event emitter that inform your component when your list is empty, if you create a stackblitz i will be able to give you more help

Upvotes: 2

Related Questions