3

I'm not sure what I'm doing here. I have this ngSwitch inside ngFor

          <li class="b-inBoxItem" *ngFor="let item of uploader.queue">
                <div [ngSwitch]="item.file.name">
                    <span *ngSwitchCase="item.file.name.includes('.png')" class="ic ic-file-image"></span>
                    <span *ngSwitchCase="item.file.name.includes('.jpeg')" class="ic ic-file-image"></span>
                    <span *ngSwitchCase="item.file.name.includes('.doc')" class="ic ic-file-stats"></span>
                        .
                        .
                        .
                    <span *ngSwitchDefault class="ic ic-file-empty"></span>
                </div>
          </li>

when I look in the debugger, I can see that the first case .png is being evaluated as true:

<!--bindings={
    "ng-reflect-ng-switch-case": "true"
}-->

Rest of them are evaluated as false.

however, only the default item is being displayed.

What am I doing wrong here?

Tom

Tomasz Golinski
  • 743
  • 5
  • 25

1 Answers1

5

The ngSwitch directive is similar to the switch statement. It displays the element for which the ngSwitchCase value is equal to the ngSwitch variable. Here is an example taken from this Rangle.io article:

<div [ngSwitch]="tab">
  <app-tab-content *ngSwitchCase="1">Tab content 1</app-tab-content>
  <app-tab-content *ngSwitchCase="2">Tab content 2</app-tab-content>
  <app-tab-content *ngSwitchCase="3">Tab content 3</app-tab-content>
  <app-tab-content *ngSwitchDefault>Select a tab</app-tab-content>
</div>

In your case, an expression gives a boolean value for each ngSwitchCase. You end up with the equivalent of:

<li class="b-inBoxItem" *ngFor="let item of uploader.queue">
  <div [ngSwitch]="item.file.name">
    <span *ngSwitchCase="true" class="ic ic-file-image"></span>
    <span *ngSwitchCase="false" class="ic ic-file-image"></span>
    <span *ngSwitchCase="false" class="ic ic-file-stats"></span>
      .
      .
      .
    <span *ngSwitchDefault class="ic ic-file-empty"></span>
  </div>
</li>

The default span is displayed because item.file.name is not equal to true or false.


To make it work, specify the file extension in ngSwitch and test the possible values:

<li class="b-inBoxItem" *ngFor="let item of uploader.queue">
  <div [ngSwitch]="getFileExtension(item.file.name)">
    <span *ngSwitchCase="'png'" class="ic ic-file-image"></span>
    <span *ngSwitchCase="'jpeg'" class="ic ic-file-image"></span>
    <span *ngSwitchCase="'doc'" class="ic ic-file-stats"></span>
      .
      .
      .
    <span *ngSwitchDefault class="ic ic-file-empty"></span>
  </div>
</li>

with the method (see this post):

getFileExtension(filename: string): string {
  return filename.split('.').pop();
}

An alternative solution is to use ngIf:

<li class="b-inBoxItem" *ngFor="let item of uploader.queue">
  <div>
    <span *ngIf="item.file.name.includes('.png')" class="ic ic-file-image"></span>
    <span *ngIf="item.file.name.includes('.jpeg')" class="ic ic-file-image"></span>
    <span *ngIf="item.file.name.includes('.doc')" class="ic ic-file-stats"></span>
      .
      .
      .
    <span *ngIf="!item.file.name.includes('.png') && !item.file.name.includes('.jpeg') && !item.file.name.includes('.doc')" class="ic ic-file-empty"></span>
  </div>
</li>
ConnorsFan
  • 70,558
  • 13
  • 122
  • 146