CPCODELAB
Angular

Structural Directives: @if and @for

10 min read

Controlling Template Structure

Structural directives add, remove, or repeat DOM elements based on conditions or collections. Angular 17 introduced a new built-in control flow syntax using @if, @for, and @switch blocks directly in templates. This replaces the older *ngIf and *ngFor attribute-based syntax.

@if for Conditional Rendering

html
@if (isLoggedIn) {
  <p>Welcome back, {{ user.name }}!</p>
  <button (click)="logout()">Log out</button>
} @else if (isLoading) {
  <p>Loading...</p>
} @else {
  <a href="/login">Please log in</a>
}

@for for List Rendering

ts
import { Component } from '@angular/core';

interface Product {
  id: number;
  name: string;
  price: number;
}

@Component({
  selector: 'app-product-list',
  standalone: true,
  template: `
    <ul>
      @for (product of products; track product.id) {
        <li>{{ product.name }} — {{ product.price | currency }}</li>
      } @empty {
        <li>No products found.</li>
      }
    </ul>
  `
})
export class ProductListComponent {
  products: Product[] = [
    { id: 1, name: 'Keyboard', price: 49.99 },
    { id: 2, name: 'Mouse', price: 29.99 },
    { id: 3, name: 'Monitor', price: 299.00 }
  ];
}

The track expression in @for is required. It tells Angular how to identify items for efficient DOM updates. Always track by a unique identifier like item.id, not by index unless you have no other option.

The older *ngIf and *ngFor attribute directives still work but are considered legacy. New Angular projects should use the @if/@for block syntax for better performance and readability.

Ready to test yourself?
Practice Angular— quiz & coding exercises