NgSwitch in Angular

Back to home
Logicmojo - Updated Aug 28, 2021



NgSwitch in Angular

Surely you’ve heard of the switch clause in general programming languages like C and C++. It’s a flow control statement that executes one block of code among many. Angular uses something similar. This brief article on Angular NgSwitch will tell you what the Angular NgSwitch directive does, with a simple demo to show its working.

What is Angular NgSwitch?

The [ngSwitch] directive on a container specifies an expression to match against. The expressions to match are provided by ngSwitchCase directives on views within the container.

• It renders every view that matches.
• If there are no matches, the view with the NgSwitchDefault directive is rendered.
• Elements outside of any NgSwitchCase or NgSwitchDefault directive but within the NgSwitch statement but are preserved at the location.

The following is the syntax of ngSwitch. It contains three separate directives. ngSwitch, ngSwitchCase & ngSwitchDefault.

<container_element [ngSwitch]="switch_expression">
    <inner_element *ngSwitchCase="match_expresson_1">...</inner_element>
    <inner_element *ngSwitchCase="match_expresson_2">...</inner_element>
    <inner_element *ngSwitchCase="match_expresson_3">...</inner_element>
    <inner_element *ngSwitchDefault>...</element>
</container_element>



ngSwitch

ngSwitch is bound to container_element like div etc. We assign a switch-expression to the ngSwitch via property binding syntax. Angular evaluates the switch_expression at runtime and based on its value displays or removes the elements from the DOM.

ngSwitchCase

ngSwitchCase is bound to an inner_element, which we must place inside the container_element. We use * (Asterix symbol), because it is a structural directive. We also assign a match_expression, which Angular evaluates at runtime. The Angular displays the inner_element only when the value of the match_expression matches the value of the switch_expression else it is removed from the DOM.

💡 Note that the ngSwitchCase does not hide the element, but removes them from the DOM.

ngSwitchDefault

ngSwitchDefault is also bound to an inner_element, which we must place inside the container_element. But it does not have any match_expression. If none of the ngSwitchCase match_expression matches the switch_expression, then the angular displays the element attached to the ngSwitchDefault

You can place ngSwitchDefault anywhere inside the container element and not necessarily at the bottom.

You are free to add more than one ngSwitchDefault directive. Angular displays all of them.

Important Points

⮞ You must place ngSwitchCase & ngSwitchDefault inside the ngSwitch directive
⮞ Angular displays every element, that matches the switch_expression
⮞ If there are no matches, angular displays all the elements, which has ngSwitchDefault directive
⮞ You can place one or more than one ngSwitchDefault anywhere inside the container element and not necessarily at the bottom.
⮞ Any element within the ngSwitch statement but outside of any NgSwitchCase or ngSwitchDefault directive is displayed as it is.
⮞ The elements are not hidden but removed from the DOM.
⮞ Angular uses loose equality checks to compare the ngSwitchCase expression with the ngSwitch expression. This means that the empty string "" matches 0.
⮞ You can share the template between multiple ngSwitchCase using the ngTemplateOutlet

NgSwitch Example

Let’s imagine we wanted to print peoples names in different colours depending on where they are from. Green for UK, Blue for USA, Red for HK.
With Bootstrap we can change the text color by using the text-danger, text-success, text-warning and text-primary classes.
We could solve this by having a series of *ngIf statements, like so:

<ul *ngFor="let person of people">
  <li *ngIf="person.country ==='UK'"
      class="text-success">{{ person.name }} ({{ person.country }})
  </li>
  <li *ngIf="person.country === 'USA'"
      class="text-primary">{{ person.name }} ({{ person.country }})
  </li>
  <li *ngIf="person.country === 'HK'"
      class="text-danger">{{ person.name }} ({{ person.country }})
  </li>
  <li *ngIf="person.country !== 'HK' && person.country !== 'UK' && person.country !== 'USA'"
      class="text-warning">{{ person.name }} ({{ person.country }})
  </li>
</ul>



This initially seems to make sense until we try to create our else style element. We have to check to see if the person is not from any of the countries we have specified before. Resulting in a pretty long ngIf expression and it will only get worse the more countries we add.
Most languages, including JavaScript, have a language construct called a switch statement to solve this kind of problem. Angular also provides us with similar functionality via something called the NgSwitch directive.
This directive allows us to render different elements depending on a given condition, in fact the NgSwitch directive is actually a number of directives working in conjunction, like so:

@Component({
  selector: 'ngswitch-example',
  template: `<h4>NgSwitch</h4>
<ul *ngFor="let person of people"
    [ngSwitch]="person.country"> (1)

  <li *ngSwitchCase="'UK'" (2)
      class="text-success">{{ person.name }} ({{ person.country }})
  </li>
  <li *ngSwitchCase="'USA'"
      class="text-primary">{{ person.name }} ({{ person.country }})
  </li>
  <li *ngSwitchCase="'HK'"
      class="text-danger">{{ person.name }} ({{ person.country }})
  </li>
  <li *ngSwitchDefault (3)
      class="text-warning">{{ person.name }} ({{ person.country }})
  </li>
</ul>`
})
class NgSwitchExampleComponent {

  people: any[] = [
    {
      "name": "Douglas  Pace",
      "age": 35,
      "country": 'MARS'
    },
    {
      "name": "Mcleod  Mueller",
      "age": 32,
      "country": 'USA'
    },
    {
      "name": "Day  Meyers",
      "age": 21,
      "country": 'HK'
    },
    {
      "name": "Aguirre  Ellis",
      "age": 34,
      "country": 'UK'
    },
    {
      "name": "Cook  Tyson",
      "age": 32,
      "country": 'USA'
    }
  ];
}


⮞ We bind an expression to the ngSwitch directive.

⮞ The ngSwitchCase directive lets us define a condition which if it matches the expression in (1) will render the element it’s attached to.

⮞ If no conditions are met in the switch statement it will check to see if there is an ngSwitchDefault directive, if there is it will render the element that’s attached to, however it is optional — if it’s not present it simply won’t display anything if no matching ngSwitchCase directive is found.

⮞ The key difference between the ngIf solution is that by using NgSwitch we evaluate the expression only once and then choose the element to display based on the result.

Output:


Conclusion

AngularJS is a great multi-functional framework which speeds up your development process. It offers dependency injection and deep linking, and is a robust platform for software development.