Search code examples
angularangular-ng-if

Only display else block if ALL options in *ngIf fail to be true


I have multiple options in an *ngIf seperated by the || operator. I also have a else operator setup to show if nothing is true. Problem is, it displays the else block on each operation rather than overall.

NgIf Block with ngFor

<ng-container *ngFor="let expense of expenses">
     <div *ngIf="sortBy && sortByColor && sortCategory.color == expense.category.color || sortBy && sortByTitle && sortCategory.title == expense.category.title || !sortBy; else elseBlock>
         ....
     </div>
     <ng-template #elseBlock>
         <p>This is the else block that should show up only when nothing is displayed above.</p>
     </ng-template>
</ng-container>

I only want the else block to show up if nothing is displayed in the ngFor at all based on the paramaters set forth in the ngIf instead right now it displays the else on each run of ngFor.


Solution

  • To have only one elseBlock displayed, you should put it outside of the ngFor loop, in an outer ngIf condition. If you put the condition in a method of the component defined as an arrow function:

    isSortedExpense = (expense) => {
      return !this.sortBy ||
        this.sortByColor && this.sortCategory.color == expense.category.color || 
        this.sortByTitle && this.sortCategory.title == expense.category.title;
    }
    

    you can call it in the outer ngIf and in the inner ngIf. The presence of at least one displayed item can be tested with Array.some():

    <ng-container *ngIf="expenses?.some(isSortedExpense); else elseBlock"> 
      <ng-container *ngFor="let expense of expenses">
         <div *ngIf="isSortedExpense(expense)">
           ....
         </div>
      </ng-container>
    </ng-container>
    <ng-template #elseBlock>
      <p>This is the else block that should show up only when nothing is displayed above.</p>
    </ng-template>