Using *ngIf and *ngFor together. Is there any other option than what I am using currently?

Viewed 70

I want to use something like below

<div *ngIf="true" *ngFor="let order of orders">
  <li></li>
</div>

I googled but there is nothing i found.

So I used below

<div *ngIf="true">
   <div *ngFor="let order of orders">
      <li></li>
   </div>
</div>

The question is; is there any better way than this?

3 Answers

Yes, there is a better way. Use ng-container

<ng-container *ngIf="true">
  <div *ngFor="let order of orders">
      <li></li>
  </div>
</ng-container>

Reason: when you use ng-container, the element will not be added to the DOM

You cannot use two structural directives in the same element. That is because the expressions *ngIf and *ngFor are microsyntax that will be expanded to the following statements respectively.

<ng-template [ngIf]="true">
  <div></div>
</ng-template>
<ng-template ngFor let-order [ngForOf]="orders">
  <li></li>
</ng-template>

So if you use two directives, the microsyntax expression wouldn't recognize which directive to expand.

The second option of using two different tags (or ng-container tag like other answers mentioned) to apply the directives is the correct way to use it.


Looking at this expansion also explains why the else clause in a *ngIf microsyntax expression is wrapped using ng-template tag.


One more additional titbit. Most of the punctuation marks in the microsyntax expressions are optional.

For eg.

<div *ngIf="condition; else elseBlock">

is the same as

<div *ngIf="condition else elseBlock">

And

<li *ngFor="let user of users; index as i; first as isFirst">

is the same as

<li *ngFor="let user of users index as i first as isFirst">

The better way is to use the special ng-container tag. This will not result in an actual html element, but into a comment:

<ng-container *ngIf="true">
   <div *ngFor="let order of orders">
      <li></li>
   </div>
</ng-container>
Related