Mastering Angular Built-in Directives: ngIf, ngFor, and ngClass

In Angular, directives are powerful tools that allow you to manipulate the DOM (Document Object Model) dynamically. They act as instructions to the HTML compiler, telling it how to transform the appearance or behavior of an element. In this guide, we will explore the three most commonly used built-in directives: ngIf, ngFor, and ngClass.

Before diving in, it is important to understand that these are divided into two categories: Structural Directives (which change the DOM structure by adding or removing elements) and Attribute Directives (which change the appearance or behavior of an existing element).

The *ngIf Directive: Conditional Rendering

The *ngIf directive is a structural directive used to include or exclude an HTML element based on a boolean condition. If the expression evaluates to true, the element is added to the DOM; otherwise, it is removed entirely.

Basic Syntax

<p *ngIf="isLoggedIn">Welcome back, User!</p>

Using ngIf with an Else Block

Angular allows you to define an alternative template to display when the condition is false using the else keyword and an ng-template.


<div *ngIf="isLoaded; else loadingTemplate">
    Content is ready to view.
</div>

<ng-template #loadingTemplate>
    <p>Loading data, please wait...</p>
</ng-template>
    

The *ngFor Directive: Iterating Over Collections

The *ngFor directive is used to repeat a piece of HTML for each item in a list or array. It is essential for building dynamic tables, lists, and grids.

Basic Syntax


<ul>
    <li *ngFor="let product of products">
        {{ product.name }} - {{ product.price | currency }}
    </li>
</ul>
    

Accessing Index and Other Variables

Angular provides several exported values that you can use inside the loop:

  • index: The current item's index (starts at 0).
  • first: True if the item is the first in the list.
  • last: True if the item is the last in the list.
  • even/odd: True if the index is even or odd.

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

The [ngClass] Directive: Dynamic Styling

Unlike the previous two, ngClass is an attribute directive. It allows you to add or remove multiple CSS classes simultaneously based on a dynamic expression.

Using an Object Literal

The most common way to use ngClass is by passing an object where the key is the class name and the value is a boolean condition.


<button [ngClass]="{'btn-active': isActive, 'btn-disabled': !isValid}">
    Submit
</button>
    

Logic Flow of Directives

Understanding how Angular decides what to render can be visualized as follows:

  • Check Condition: Is the expression in *ngIf true?
    • Yes: Render the element.
    • No: Check if an "else" template exists. If yes, render it. If no, render nothing.
  • Iterate List: Does the array in *ngFor have items?
    • Yes: Create a new DOM element for every item in the array.
    • No: Render nothing.

Common Mistakes to Avoid

  • Multiple Structural Directives: You cannot put two structural directives (like *ngIf and *ngFor) on the same HTML element. To solve this, wrap one in a container or an ng-container.
  • Forgetting the Asterisk: Structural directives require the * prefix (e.g., *ngIf). Forgetting it will cause a template error.
  • Performance with ngFor: When updating large lists, Angular re-renders all items. Use the trackBy function to improve performance by telling Angular how to identify unique items.

Real-World Use Cases

  • Authentication: Using *ngIf to show a "Logout" button only when a user is authenticated.
  • Data Tables: Using *ngFor to loop through API response data and display it in a structured table.
  • Theming: Using [ngClass] to switch between "Dark Mode" and "Light Mode" by applying a global class to a container.
  • Form Validation: Using [ngClass] to highlight input fields in red when the user enters invalid data.

Interview Preparation Notes

  • Question: What is the difference between *ngIf and [hidden]?
  • Answer: *ngIf physically removes or adds the element from the DOM, which is better for performance if the element is heavy. [hidden] uses CSS (display: none) to hide the element, meaning the element still exists in the DOM.
  • Question: Why is trackBy used in *ngFor?
  • Answer: It helps Angular identify which items have changed, been added, or removed. This prevents the entire list from being re-rendered, significantly improving performance in large collections.
  • Question: Can you create custom directives?
  • Answer: Yes, while Angular provides built-in ones, developers can use the @Directive decorator to create custom behavior.

Summary

Built-in directives are the backbone of dynamic Angular applications. *ngIf handles conditional logic, *ngFor manages collections and loops, and [ngClass] provides a flexible way to manage CSS classes. By mastering these three, you can create highly interactive and responsive user interfaces. Remember to use ng-container when you need to apply multiple structural logic rules without adding extra tags to your HTML structure.

In the next part of our Complete Angular Masterclass, we will explore Component Communication and how to pass data between parent and child components.