Search code examples
angularangular-directive

Angular ngIf else is not working inside ng-container


Am trying to implement ngif else in Angular12. But for some reason else part is not getting executed.The problem is if the image is not null it has to generate the cards with image. If the image is null i want some text inside the card mentioning "IMAGE NOT AVALIABLE".The else part is not working.can someone steer me in the right direction. Thanks

<ng-template [ngIf]="seasonsdetail.season?.length">
      <ng-container *ngFor = "let seasons of seasonsdetail.season">
        <div class="col-sm-2 col-md-3 col-lg-3">
          <ng-container *ngIf="seasons.image.medium; else elseTemplate">
            <div class="card" data-id='' >
                <a href= ''><img class="card-img img-fluid " [src]='seasons.image.medium' alt="Seasons"></a>
            </div>
            <h4 class="card-title">
              {{seasons.number}}
            </h4>
          </ng-container>
        </div>
        <ng-template #elseTemplate>
          <div class="card" data-id='' >
            <!--<div class="card-body"> -->
              <h4>Image not Avaliable</h4>
            <!--</div>-->
          </div>
          <h4 class="card-title">
            {{seasons.number}}
         </h4>         
        </ng-template>
      </ng-container>
    </ng-template>
 

Solution

  • ISSUE

    From the question, seasons.image is possible to be null.

    It works when seasons.image is not null, thus you can access seasons.image.medium.

    However, when seasons.image is null and you don't handle for null scenario, you will get this error and the #elseTemplate is not generated.

    ERROR Error: Cannot read property 'medium' of null


    SOLUTION 1

    You have to apply Typescript Optional Chaining to handle the null scenario for seasons.image.

    <ng-container *ngIf="seasons.image?.medium; else elseTemplate">
    

    Full HTML template:

    <ng-template [ngIf]="seasonsdetail.season?.length">
      <ng-container *ngFor="let seasons of seasonsdetail.season">
        <div class="col-sm-2 col-md-3 col-lg-3">
          <ng-container *ngIf="seasons.image?.medium; else elseTemplate">
            <div class="card" data-id=''>
              <a href=''><img class="card-img img-fluid " [src]='seasons.image.medium' alt="Seasons"></a>
            </div>
            <h4 class="card-title">
              {{seasons.number}}
            </h4>
          </ng-container>
        </div>
        <ng-template #elseTemplate>
          <div class="card" data-id=''>
            <!--<div class="card-body"> -->
            <h4>Image not Avaliable</h4>
            <!--</div>-->
          </div>
          <h4 class="card-title">
            {{seasons.number}}
          </h4>
        </ng-template>
      </ng-container>
    </ng-template>
    

    Solution 1 on StackBlitz


    SOLUTION 2

    Based on your latest comment, you try to discard the #elseTemplate and handle for null sessions.image in the same ngContainer. Yes, you can do in that way.

    And you need to remove ngIf logic from the ngContainer.

    <img class="card-img img-fluid " [src]='seasons.image ? seasons.image.medium : "assets/img/noimage.png">
    

    Full HTML Template

    <ng-template [ngIf]="seasonsdetail.season?.length">
      <ng-container *ngFor="let seasons of seasonsdetail.season">
        <div class="col-sm-2 col-md-3 col-lg-3">
          <ng-container>
            <div class="card" data-id=''>
              <a href=''><img class="card-img img-fluid " [src]='seasons.image ? seasons.image.medium : "assets/img/noimage.png"' alt="Seasons"></a>
            </div>
            <h4 class="card-title">
              {{seasons.number}}
            </h4>
          </ng-container>
        </div>
      </ng-container>
    </ng-template>
    

    Solution 2 on StackBlitz