Angular Built In Structural Directives Ngif Ngfor Complete Guide

 Last Update:2025-06-23T00:00:00     .NET School AI Teacher - SELECT ANY TEXT TO EXPLANATION.    6 mins read      Difficulty-Level: beginner

Understanding the Core Concepts of Angular Built in Structural Directives ngIf, ngFor

Angular Built-in Structural Directives: *ngIf and *ngFor

In building dynamic web applications with Angular, one of the foundational capabilities provided by the framework are structural directives. These directives not only influence how a particular template behaves under various conditions but also help in managing DOM elements efficiently. Among them, *ngIf and *ngFor stand out as extremely powerful and essential tools for data manipulation and rendering components based on specific criteria.

1. *ngIf Directive

*ngIf is a fundamental directive used to conditionally include or exclude a portion of HTML based on the truthiness of an expression. It is incredibly useful when you need to render content dynamically and ensure that unnecessary parts of the DOM are not created and remain uninitialized, thus optimizing performance and resource usage.

Syntax:

<element *ngIf="conditionExpression; else #templateRef">
  <!-- Content to be rendered if the conditionExpression evaluates to true -->
</element>
<ng-template #templateRef>
  <!-- Content to be rendered if the conditionExpression evaluates to false -->
</ng-template>
  • conditionExpression: This expression can be any valid Angular boolean expression. If it evaluates to true, the element containing *ngIf remains in the DOM. If evaluation returns false, Angular removes the element from the DOM.
  • else: This part allows you to specify an ng-template reference that will be displayed when the primary condition is false. Utilizing else enhances code readability and avoids the need for additional if-else logic in your component files.

Example Usage:

// user.component.ts
export class UserComponent {
  isLoggedIn: boolean = true;
}
<!-- user.component.html -->
<div *ngIf="isLoggedIn; else notLoggedIn">
  Welcome, User!
</div>
<ng-template #notLoggedIn>
  Please log in.
</ng-template>
  • Performance Considerations: Since elements added and removed by *ngIf get initialized and destroyed, overusing it can degrade application performance, especially in complex components. For scenarios where frequent visibility toggling is necessary, consider using *ngStyle or *ngClass.

2. *ngFor Directive

*ngFor provides a way to iterate over a collection of items (like arrays) and generate new DOM elements for each item in the collection. It is indispensable for rendering lists, tables, repetitive UI patterns, and more within Angular applications.

Syntax:

<element *ngFor="let item of array | pipe; index as i; first as isFirst; last as isLast; odd as isOdd; even as isEven;">
  <!-- Template content goes here -->
</element>
  • let item of array: This is essential for defining a variable (item) that represents the current item in the iteration.
  • Optional Variables:
    • index as i: Provides the current index of the array item.
    • first as isFirst: A boolean value indicating whether the current item is the first in the iteration.
    • last as isLast: Denotes whether the current item is the last in the array.
    • odd as isOdd: Determines if the current index is odd.
    • even as isEven: Checks if the current index is even.
  • pipe: Allows you to apply pipes to transform data before iterating over it.

Example Usage:

// products.component.ts
export class ProductsComponent {
  products: Array<string> = ['Laptop', 'Smartphone', 'Tablet'];
}
<!-- products.component.html -->
<ul>
  <li *ngFor="let product of products; index as i; first as isFirst; last as isLast;">
    {{ i }}. {{ product }}
    <span *ngIf="isFirst">First Product</span>
    <span *ngIf="isLast">Last Product</span>
  </li>
</ul>

Key Points about *ngFor:

  • TrackBy Function: By default, Angular recreates DOM nodes whenever there's any change in the array. To optimize this behavior, particularly for large lists, use the trackBy function, which instructs Angular to track elements by a unique identifier rather than by index. This prevents unnecessary re-rendering and improves performance.
export class ProductsComponent {
  products: Array<{ id: number, name: string }> = [
    { id: 1, name: 'Laptop' },
    { id: 2, name: 'Smartphone' },
    { id: 3, name: 'Tablet' }
  ];

  trackById(index: number, product: { id: number, name: string }) {
    return product.id;
  }
}
<ul>
  <li *ngFor="let product of products; trackBy: trackById">
    {{ product.name }}
  </li>
</ul>
  • Nested Iteration: *ngFor can be nested to handle multi-dimensional arrays or objects with nested structures. However, excessive nesting might affect readability and performance, so use it judiciously.
// categories.component.ts
export class CategoriesComponent {
  categories: Array<Array<string>> = [
    ['Electronics', 'Tech Gadgets'],
    ['Clothing', 'Fashion Items']
  ];
}
<!-- categories.component.html -->
<div *ngFor="let category of categories; let outerIndex = index;">
  Category Group {{ outerIndex + 1 }}:
  <ul>
    <li *ngFor="let item of category; let innerIndex = index;">
      {{ item }} ({{ innerIndex + 1 }})
    </li>
  </ul>
</div>

Importance of *ngIf and *ngFor in Web Development

Understanding and effectively utilizing *ngIf and *ngFor is crucial for developers working with Angular, as they enable efficient data rendering and UI manipulation. Here’s why these directives are so important:

  • Dynamic Content Rendering: Both directives allow for dynamic content generation based on runtime conditions or data arrays. This makes applications more flexible and responsive to user actions and changes in data.

  • Improved Application Performance: By controlling the inclusion/exclusion of DOM elements via *ngIf and optimizing list rendering with *ngFor (specifically through trackBy), applications load faster and utilize system resources more efficiently.

  • Maintainability: Clean and readable templates are easier to maintain, debug, and extend. Directives like *ngIf and *ngFor promote a modular approach to handling conditions and iterations.

  • Reusability: You can reuse components across different parts of your application, passing data arrays or booleans as inputs to control their behavior dynamically.

In summary, Angular's *ngIf and *ngFor directives are critical for conditional rendering and efficient list management within applications. Mastering their usage enhances your development workflow and contributes significantly to building scalable and performant web applications.

Online Code run

🔔 Note: Select your programming language to check or run code at

💻 Run Code Compiler

Step-by-Step Guide: How to Implement Angular Built in Structural Directives ngIf, ngFor

Prerequisites:

  • You should have Angular CLI installed. If not, you can install it using:
    npm install -g @angular/cli
    
  • Create a new Angular project or use an existing one:
    ng new example-angular-app
    cd example-angular-app
    

Creating a Simple Component

Let's create a simple component to demonstrate *ngIf and *ngFor.

  1. Generate a New Component:

    ng generate component user-list
    

    This command generates a new component named user-list with associated template, style files, etc.

  2. Implement the Component Logic:

    Open the user-list.component.ts file and modify it to include an array of user data.

    import { Component } from '@angular/core';
    
    @Component({
      selector: 'app-user-list',
      templateUrl: './user-list.component.html',
      styleUrls: ['./user-list.component.css']
    })
    export class UserListComponent {
      showUsers: boolean = true;
      users: string[] = [
        'Alice',
        'Bob',
        'Charlie',
        'Diana'
      ];
    
      toggleShowUsers() {
        this.showUsers = !this.showUsers;
      }
    }
    

    Explanation:

    • showUsers: a boolean property to control the visibility of the user list.
    • users: an array of strings representing the names of users.
    • toggleShowUsers: a method to toggle the value of showUsers.
  3. Update the Component Template:

    Open the user-list.component.html file and add the following code to use the *ngIf and *ngFor directives.

    <div>
      <h2>User List</h2>
      <button (click)="toggleShowUsers()">
        {{ showUsers ? 'Hide Users' : 'Show Users' }}
      </button>
    
      <ul *ngIf="showUsers">
        <li *ngFor="let user of users; let i = index">
          {{ i + 1 }}. {{ user }}
        </li>
      </ul>
    
      <p *ngIf="!showUsers">No users to display.</p>
    </div>
    

    Explanation:

    • *ngIf="showUsers": Displays the user list only if showUsers is true.
    • *ngFor="let user of users; let i = index": Iterates over the users array and generates a list item (<li>) for each user. let i = index assigns the current index to the variable i, which is used to display the user's rank in the list.
    • Another *ngIf="!showUsers": Displays the message "No users to display." only if showUsers is false.
  4. Add the Component to Your Application:

    To display the UserListComponent, add the <app-user-list></app-user-list> selector in your main application component template, usually located at app.component.html.

    <app-user-list></app-user-list>
    
  5. Run the Application:

    Run the Angular application to see the UserListComponent in action.

    ng serve
    

    Open your browser and navigate to http://localhost:4200. You will see a button labeled "Show Users." Clicking the button will toggle the visibility of the user list.

Summary:

  • *ngIf: Conditionally includes or excludes a portion of the template based on the expression's value.
  • *ngFor: Repeats a template for each item in a collection.

Top 10 Interview Questions & Answers on Angular Built in Structural Directives ngIf, ngFor

Q1: What is a Structural Directive in Angular?

A: A Structural Directive in Angular is a type of directive that helps control how DOM elements are added or removed from the DOM, essentially modifying the layout or structure of the view. They are denoted by an asterisk (*) prefix. Some common examples include *ngIf, *ngFor, and *ngSwitch.

Q2: Can you explain how the *ngIf directive works?

A: The *ngIf directive is used to conditionally add or remove an element from the DOM based on the evaluation of a given expression. If the expression evaluates to true, the element is included in the DOM; if it evaluates to false, it is not added. This directive helps in improving performance by only including elements when necessary.

<!-- Example usage -->
<div *ngIf="isLoggedIn; else loggedOut">
  Welcome, User!
</div>
<ng-template #loggedOut>
  Please log in.
</ng-template>

Q3: How do I use *ngIf with an else block?

A: You can conditionally render content using *ngIf along with an else template reference. For instance:

<div *ngIf="condition; else noData">
  Data is available.
</div>
<ng-template #noData>
  No data is available.
</ng-template>

In this example, if condition is true, "Data is available." will be displayed; otherwise, "No data is available." from the noData template will be rendered.

Q4: What happens if the condition provided to *ngIf changes over time?

A: When the condition provided to *ngIf changes, Angular automatically updates the DOM according to the new value. If the condition was false and became true, Angular adds the respective element to the DOM. Conversely, if the condition was true and becomes false, Angular removes that specific element from the DOM.

Q5: What is the purpose of *ngFor directive?

A: The *ngFor directive is utilized to iterate over collections (like arrays) and generate elements dynamically based on each item in the collection. It is used to render lists of data efficiently.

<ul>
  <li *ngFor="let user of users">{{ user.name }}</li>
</ul>

Here, users is an array of objects, each having a name property, and we create a list item (<li>) for every user object within the users array.

Q6: How do you access the index of items in *ngFor?

A: To access the index of items while iterating with *ngFor, you can use the index variable:

<ul>
  <li *ngFor="let user of users; let i = index">User {{i + 1}}: {{ user.name }}</li>
</ul>

This will display "User 1:", "User 2:", etc., before the names of the users.

Q7: Can I use multiple variables in *ngFor?

A: Yes, you can leverage several variables in *ngFor, including first, last, even, odd, index, and count. These allow you to apply conditional logic based on the position or properties of the iterated items:

<div *ngFor="let product of products; let first = isFirst; let last = isLast">
  Product: {{product.name}}, First: {{isFirst}}, Last: {{isLast}}
</div>

Q8: Is it possible to render a custom template using *ngFor?

A: Yes, similar to *ngIf, *ngFor allows rendering a custom template. You can use the ng-template tag as follows:

<ul>
  <ng-template ngFor let-product [ngForOf]="products" let-i="index">
    <li *ngIf="i % 2 === 0">
      Product at even index: {{product.name}}
    </li>
  </ng-template>
</ul>

Here, an <li> element is added to the list only when the index (i) is even.

Q9: How does Angular handle trackBy in *ngFor?

A: Using trackBy, Angular allows optimization during the update process by identifying unique items. This prevents unnecessary re-rendering and improves performance, especially for large lists or lists with many updates.

// In your component class
trackById(index: number, product: any): any {
  return product.id;
}
<ul>
  <li *ngFor="let product of products; trackBy: trackById">{{ product.name }}</li>
</ul>

The trackById function ensures that Angular tracks each item by its ID, rather than the default behavior of tracking by their index.

Q10: What are some best practices when using *ngIf and *ngFor together?

A: When combining *ngIf and *ngFor for better performance and cleaner code, consider the following:

  • Use *ngIf above *ngFor: When using *ngIf and *ngFor on the same element, ensure *ngIf is evaluated first. Angular doesn't guarantee execution order, so applying *ngIf to parent elements where possible avoids creating and destroying child components unnecessarily.

  • Avoid combining *ngIf and *ngFor directly: Combining these directives can lead to unexpected results and poor performance because both will try to modify the DOM independently.

  • Use *ngFor inside *ngIf: To avoid creating a loop when the list is not required, place the *ngFor inside a container protected by *ngIf.

<div *ngIf="showList && products.length > 0">
    <ul>
      <li *ngFor="let product of products">{{ product.name }}</li>
    </ul>
</div>
<div *ngIf="!showList || products.length === 0">
    There are no products to show.
</div>

In this example, the list is only rendered if both showList is true and the products array contains elements. The second *ngIf handles cases where the products should not be listed.

You May Like This Related .NET Topic

Login to post a comment.