[Fixed] Angular select visible element based on some value

Issue

I get a list of items from a service as an (observable) array. The elements in the have a type: string; field, which I intend to use as an indicator for selecting different components to display. When I don’t have a widget for a type yet, I want to display the type as a string.

Versions

When I forgot something, let me know, and I will add it.

module version
node v14.2.0
Angular CLI 9.1.6
npm 6.14.4
@angular/core ~9.1.7

What I got so far

The component template I’m using

<mat-grid-list cols="8" rowHeight="1:1" class="grid">
  <ng-container *ngFor="let widget of widgets |async">
    <mat-grid-tile class="grid-item">
      <div [ngSwitch]="widget.type">
        <app-light-toggle [widget]="widget" *ngSwitchWhen="light"></app-light-toggle>
        <div *ngSwitchDefault>
          {{widget.type}}
        </div>
      </div>
    </mat-grid-tile>
  </ng-container>
</mat-grid-list>

The widget class with the field:

export class Widget {
  // other fields left out, because irrelevant.
  type: string;

  constructor(type :string) {
    this.type = type;
  }
}

What I would expect

Then the type value is equal to light select the first case, which would display the widget for light. When the type is equal to anything else, display the type variable in the tile

What I get

The result

Notes

  • When removing the ng-switch-default div, both tiles show the app-light-toggle.
  • I found several different notations for the switch syntax and am rather lost on which one to use
    • NgSwitch results in an error, which personally tells me nothing (ERROR Error: No provider for TemplateRef)
      • Does this mean, I can provide templates somewhere?
      • If so, where do I do this? I can’t seem to find anything regrading a template store or anything in the documentation
    • ng_ng-switch does seem to do something, but does not behave as I would expect (see explanation above)

Updates

  1. I added an asterisk before ngSwitchWhen, which fixed the template error, I think. But still I get the wrong option selected.
  2. I found out, that both elements get rendered on top of each other.
  3. Added the angular version
  4. Added Solution
  5. Moved solution to stackblitz

Solution

The Solution Provided by @Poul Kruijt in this answer did it for me. I was using the wrong directive and did not use quotes in the value. A simplified stackbliz version can be found here

Solution

First, it’s called ngSwitchCase. Second, You should put quotes around your *ngSwitchCase assignment, otherwise it will look for a component variable named light:

*ngSwitchCase="'light'"

Leave a Reply

(*) Required, Your email will not be published