Home > Back-end >  ngIf still renders div on false condition
ngIf still renders div on false condition

Time:08-24

I am trying to show a series of material cards based on a flag in my data. If the flag is falsy, I'm still getting an empty div (and thus extra space) injected into the DOM.

Assume I have an array of Fruit objects that have an isBanana flag. My template looks like:

<div *ngIf="fruit$ | async as fruits">
  <!-- NOT bananas -->
  <div *ngFor="let fruit of fruits">
    <mat-card *ngIf="!fruit.isBanana" [fruit]="fruit"></mat-card>
  </div>

  <!-- Bananas -->
  <div *ngFor="let fruit of fruits">
    <mat-card *ngIf="fruit.isBanana" [fruit]="fruit"></mat-card>
  </div>
</div>

I realize it's not ideal to loop through the array twice, but due headers/sections in my actual application, that's just kinda the way it has to be.

Anyhoo, the final render in the browser is such that, in the first/non-banana section, I successfully get cards without bananas, but each time that for loop comes across a fruit object that's not a banana, it injects an empty div, which adds space between cards where there should not be, such as

<div >
  <div>
    <mat-card><!-- card template --></mat-card>
  </div>
  <div><!-- literally just an empty div --></div>
</div>

I would think that if the condition is false, nothing would be rendered, but clearly that's not the case.

CodePudding user response:

You have the conditional on the <mat-card>, so only this element gets removed. To remove the wrapping <div> you need to put the *ngIf on the <div> element. Since you cannot have two structural directives on one element, you will have to wrap the <div> with <ng-container> and move the *ngFor there. <ng-container> won't be added to the DOM, so you'll end up with the same structure as you would without it.

<div *ngIf="fruit$ | async as fruits">
  <!-- NOT bananas -->
  <ng-container *ngFor="let fruit of fruits">
    <div *ngIf="!fruit.isBanana">
      <mat-card [fruit]="fruit"></mat-card>
    </div>
  </ng-container>

  <!-- Bananas -->
  <ng-container *ngFor="let fruit of fruits">
    <div *ngIf="fruit.isBanana">
      <mat-card [fruit]="fruit"></mat-card>
    </div>
  </ng-container>
</div>
  • Related