Home » Framework » Angular » Built-in Structural Directives ngIf ngFor ngSwitch in Angular

Built-in Structural Directives ngIf ngFor ngSwitch in Angular

This article explains the most common use of built-in structural directives like ngIf, ngFor, and ngSwitch in Angular Application.

Structural directives change the appearance of the HTML layout by adding or removing the host elements attached with the directive. Here let us see the most common use of structural directives mentioned below.

  1. ngIf
  2. ngFor
  3. ngSwitch

Note: Host elements are the elements attached with the angular directive. In the below example the tag h2 is the host element that is attached with the angular directive ngIf.

<h2 *ngIf="true"></h2>

ngIf Directive in Angular

ngIf adds or removes the element based on the condition written inside. If the condition is true then it shows the element and if the condition is false it removes the element and its descendants and frees up the memory.

Let us see the examples below. We have already seen the examples of built-in attribute directives in the last article with the newly created angular application. Here we are going to use the same angular project named 'angular-directive' to see the examples of built-in structural directives.

Create a component named 'ngif' by using the below command.

ng g c ngif

The above command creates the component under the app folder named 'ngif'. In this component let us write the examples of ngIf.

Open the ngif.component.html file and replace it with the below code.

<h2>NgIf Examples</h2>
<h3>Student Mark List</h3>
<table>
  <thead >    
    <th>Student Name</th>
    <th>Score</th>
    <th>Result</th>
  </thead>
  <tr *ngFor="let student of studentList" >      
    <td>{{student.name}}</td> 
    <td>{{student.score}}</td>
    <td *ngIf="student.status" [ngStyle]="passStyles">{{student.result}}</td>
    <td *ngIf="!student.status" [ngStyle]="failStyles">{{student.result}}</td>   
  </tr>
</table>

Replace the below code in the ngif.component.ts file

import { Component, OnInit } from '@angular/core';
@Component({
  selector: 'app-ngif',
  templateUrl: './ngif.component.html',
  styleUrls: ['./ngif.component.css']
})
export class NgifComponent implements OnInit {
  constructor() { }  
  passStyles = {
    'font-style':'italic',
      'font-weight': 'bold',
      'font-size': '16px',
      'color':'green'
  };
  failStyles = {
    'font-style':'normal',
      'font-weight': 'normal',
      'font-size': '16px',
      'color':'red'
  };  
  studentList:Array<any> =[
    {"name":"John", "score":35, "result":"PASS", "status":true},
    {"name":"Peter", "score":20, "result":"FAIL", "status":false},
    {"name":"David", "score":15, "result":"FAIL", "status":false},
    {"name":"Salman", "score":45, "result":"PASS", "status":true},
    {"name":"Khan", "score":80, "result":"PASS", "status":true}
  ];
  ngOnInit(): void {
  }
}

Replace the below code in the app.component.html file to see the result in the browser.

<h1 style="color:green;text-align: center;">Welcome to TipsToCode!</h1>
<h1>Built-in Structural Directives</h1>
<app-ngif></app-ngif>

Now run the project by using the ng serve command to see the result in the browser. It displays the student mark list and it applies the style 'passStyles' to the result column if the status is true and it applies the style 'failStyles' to the result column if the status is false.

ngIf-directive
ngIf-directive

ngIf with else

ngIf directive shows the element if the condition is true and if the condition is false it executes the else clause that normally renders the <ng-template>. The default template for the else clause is blank. Now replace the below code in the ngif.component.html file to see the effect.

<h2>NgIf and NgFor Examples</h2>
<h3>Student Mark List</h3>
<table>
  <thead >    
    <th>Student Name</th>
    <th>Score</th>
    <th>Result</th>
  </thead>
  <tr *ngFor="let student of studentList" >      
    <td>{{student.name}}</td> 
    <td>{{student.score}}</td>
    <td *ngIf="student.status; else failStyle" [ngStyle]="passStyles">{{student.result}}</td>
    <ng-template #failStyle><td [ngStyle]="failStyles">{{student.result}}</td></ng-template>  
  </tr>
</table>

The above code applies the style 'passStyles' to the result column if the condition is true else it renders the template <ng-template> with the reference id as #failStyle.

ngIf directive removes the element from the layout when the condition matches the null value. For example *ngIf="null"

Also, we can apply the structural directive in the component element like a host element. For example, see the code below.

<app-ngif *ngIf="true"></app-ngif>

The above code renders the component view in the HTML layout if the *ngIf directive evaluates as true else it removes the component view from the layout.

ngFor Directive in Angular

ngFor directive displaying the list of items in the layout. Let us see the examples below.

Run the below command to create the component named 'ngfor'.

ng g c ngfor

Replace the below code in the ngfor.component.html file

<h2>NgFor Example </h2>
<table>
  <thead >
    <th>Student ID</th>
    <th>Student Name</th>
    <th>Score</th>
    <th>Result</th>
  </thead>
  <tr *ngFor="let student of studentList" >  
    <td>{{student.id}}</td> 
    <td>{{student.name}}</td> 
    <td>{{student.score}}</td>
    <td >{{student.result}}</td>
  </tr>  
</table>

Open the file ngfor.component.ts in the editor and replace it with the below code.

import { Component, OnInit } from '@angular/core';
@Component({
  selector: 'app-ngfor',
  templateUrl: './ngfor.component.html',
  styleUrls: ['./ngfor.component.css']
})
export class NgforComponent implements OnInit {
  constructor() { }    
  studentList: any[] =[];  
  ngOnInit(): void {
    this.studentList = [
      {"id":1,"name":"John","score":35,"result":"PASS"},
      {"id":2,"name":"Salman","score":45,"result":"PASS"},
      {"id":3,"name":"Peter","score":15, "result":"FAIL"},
      {"id":4,"name":"Kamal","score":25, "result":"FAIL"}
    ]    
  }  
}

Finally, change the app.component.html file like below to see the student mark list table in the browser.

<h1 style="color:green;text-align: center;">Welcome to TipsToCode!</h1>
<h1>Built-in Structural Directives</h1>
<app-ngfor ></app-ngfor>

See this line *ngFor="let student of studentList" in the ngfor.component.html file.

  1. *ngFor Directive iterates the 'studentList' array.
  2. It stores the values of each student in the looping variable 'student'.
  3. Displays each student values in the templated HTML <td></td>.

ngFor with index

We can get the index of each item from the list of items that are displayed using the *ngFor directive.

In the above example, we can get the index of every student in the student list like below.

*ngFor="let student of studentList; let i=index"

In the above code, the variable 'i' stores the index value of each student and the index value starts from 0.

Let's add the below code in the ngfor.compoenent.html file to see the result.

<h2>NgFor Example with index </h2>
<table>
  <thead >
    <th>Index Value</th>
    <th>Student ID</th>
    <th>Student Name</th>
    <th>Score</th>
    <th>Result</th>
  </thead>
  <tr *ngFor="let student of studentList; let i=index" >  
    <td>{{i+1}}</td> 
    <td>{{student.id}}</td> 
    <td>{{student.name}}</td> 
    <td>{{student.score}}</td>
    <td >{{student.result}}</td>
  </tr>  
</table>

The above code displays the index value of each student.

ngFor with trackBy

The trackBy function of *ngFor directive tracks the items when add or remove the items from the item list. It only creates the DOM for the newly added items and it will not create the DOM for already existing items in the list.

Let see the examples for the *ngFor directive with trackBy function and without trackBy function.

Example of *ngFor directive without trackBy function

Add the below code in the ngfor.component.html file

<h3>NgFor without TrackBy </h3>
<table>
  <thead >
    <th>Student ID</th>
    <th>Student Name</th>
    <th>Score</th>
    <th>Result</th>
  </thead>
  <tr *ngFor="let student of studentList" >  
    <td>{{student.id}}</td> 
    <td>{{student.name}}</td> 
    <td>{{student.score}}</td>
    <td >{{student.result}}</td>   
  </tr>
  <button (click)="resetStudents()">Add Students</button> 
</table>

Replace the below code in the ngfor.component.ts file

import { Component, OnInit } from '@angular/core';
@Component({
  selector: 'app-ngfor',
  templateUrl: './ngfor.component.html',
  styleUrls: ['./ngfor.component.css']
})
export class NgforComponent implements OnInit {
  constructor() { }    
  studentList: any[] =[];  
  ngOnInit(): void {
    this.studentList = [
      {"id":1,"name":"John","score":35,"result":"PASS"},
      {"id":2,"name":"Salman","score":45,"result":"PASS"},
      {"id":3,"name":"Peter","score":15, "result":"FAIL"},
      {"id":4,"name":"Kamal","score":25, "result":"FAIL"}
    ]    
  }
  trackByStudents(index: number, id: any): number {
     return id;
  }
  resetStudents(){  
    this.studentList = [
      {"id":1,"name":"John","score":35,"result":"PASS"},
      {"id":2,"name":"Salman","score":45,"result":"PASS"},
      {"id":3,"name":"Peter","score":15, "result":"FAIL"},
      {"id":4,"name":"Kamal","score":25, "result":"FAIL"},
      {"id":5,"name":"Khan","score":35, "result":"PASS"},
      {"id":6,"name":"swathi","score":55, "result":"PASS"}           
    ];
  }  
}

In the above code, the function trackByStudents track the students based on the unique key id when adding the new students to the student list or remove the students from the student list.

Initially, the studentList array has set with the 4 students within the ngOnInit() function. When clicking the 'Add Student' button it adds 2 more students to the studentList array.

At this time the *ngFor directive without trackBy function removes all the DOM elements and recreates them again even the same data coming from the studentList array.

Example of *ngFor directive with trackBy function

Now let's add the below code in the ngfor.component.html file.

<h3>NgFor with TrackBy </h3>
<table>
  <thead >
    <th>Student ID</th>
    <th>Student Name</th>
    <th>Score</th>
    <th>Result</th>
  </thead>
  <tr *ngFor="let student of studentList; trackBy: trackByStudents" >  
    <td>{{student.id}}</td> 
    <td>{{student.name}}</td> 
    <td>{{student.score}}</td>
    <td >{{student.result}}</td>    
  </tr>
  <button (click)="resetStudents()">Add Students</button> 
</table>

Now if we click the 'Add Students' button then the studentList array gets updated and the trackBy function adds the DOM elements for the newly added data and not for the already existing ones. Using the trackBy function is increasing the performance of the angular applications.

Save all the changes and run the application again to see the below result in the browser.

ngFor-directive
ngFor-directive

ngSwitch Directive in Angular

ngSwitch directive displays one element based on the switch condition from among the several possible elements. There are three directives available in ngSwitch directive that are.

  1. ngSwitch
  2. ngSwitchCase
  3. ngSwitchDefault

ngSwitch - It is an attribute directive that holds the switch value.

ngSwitchCase - It is a structural directive that checks the switch value. If the switch value matches then it adds its elements to the DOM and displays it.

ngSwitchDefault - It is also a structural directive that adds its elements to the DOM when there are no matches with the ngSwitchCase.

Let us see the example by creating the new component using the below command.

ng g c ngswitch

Now open the ngswitch.component.html file and replace it with the below code.

<h2>NgSwitch Example</h2>
<div [ngSwitch]="gadgetChoice">
    <div *ngSwitchCase=1>Personal Computer</div>
    <div *ngSwitchCase=2>Laptop</div>
    <div *ngSwitchCase=3>Palmtop</div>
    <div *ngSwitchCase=4>Tablet</div>
    <div *ngSwitchCase=5>Mobile Phone</div>
    <div *ngSwitchCaseDefault>Gadget</div>
</div>

Replace the below code in the ngswitch.component.ts file

import { Component, OnInit } from '@angular/core';
@Component({
  selector: 'app-ngswitch',
  templateUrl: './ngswitch.component.html',
  styleUrls: ['./ngswitch.component.css']
})
export class NgswitchComponent implements OnInit {
  gadgetChoice = 3;
  directiveChoice = 'ngif';
  constructor() { }
  ngOnInit(): void {
  }
}

Now add this component directive in the app.component.html file like below to see the result in the browser.

<h1 style="color:green;text-align: center;">Welcome to TipsToCode!</h1>
<h1>Built-in Structural Directives</h1>
<app-ngswitch ></app-ngswitch>

Let's run the application and see the result in the browser. It displays the gadget name based on the switch value that is declared with the variable 'gadgetChoice' in the ngswitch.component.ts file.

We can also apply this ngSwitch directive to the component elements like below. Let's replace the below code in the ngswitch.component.html file and check it.

<h2>NgSwitch Example</h2>
<p>NgSwith with Component elements</p>
<div [ngSwitch]="directiveChoice">
    <app-ngclass *ngSwitchCase="'ngclass'"></app-ngclass> 
    <app-ngstyle *ngSwitchCase="'ngstyle'"></app-ngstyle>
    <app-ngmodel *ngSwitchCase="'ngmodel'"></app-ngmodel>
    <app-ngif *ngSwitchCase="'ngif'"></app-ngif>
    <app-ngfor *ngSwitchCaseDefault></app-ngfor>   
</div>
<p>NgSwith with native HTML elements</p>
<div [ngSwitch]="gadgetChoice">
    <div *ngSwitchCase=1>Personal Computer</div>
    <div *ngSwitchCase=2>Laptop</div>
    <div *ngSwitchCase=3>Palmtop</div>
    <div *ngSwitchCase=4>Tablet</div>
    <div *ngSwitchCase=5>Mobile Phone</div>
    <div *ngSwitchCaseDefault>Gadget</div>
</div>

Save all the changes and run the application again to see the result like below in the browser.

ngSwitch-directive
ngSwitch-directive

I hope you understood the most use of built-in structural directives like ngIf, ngFor, and ngSwitch in the angular application. Thanks!. Keep Reading!.

Download the full source code from GitHub.

2 thoughts on “Built-in Structural Directives ngIf ngFor ngSwitch in Angular

  1. I have been surfing online for greater than three hours for this information. Finally, I found this article really great. Thanks!.

Leave a Reply

Your email address will not be published. Required fields are marked *