Angular Built-in Control Flow

Angular Built-in Control Flow

Angular 17 introduced a new built-in control flow syntax directly in templates — replacing the older *ngIf, *ngFor, and *ngSwitch structural directives.

@if — Conditional Rendering

<!-- New syntax (Angular 17+) -->
@if (isLoggedIn) {
  <app-dashboard />
} @else if (isPending) {
  <app-loading />
} @else {
  <app-login />
}

<!-- Old syntax (still valid) -->
<div *ngIf="isLoggedIn; else loginBlock">Dashboard</div>
<ng-template #loginBlock><app-login /></ng-template>

@for — List Rendering

<ul>
  @for (user of users; track user.id) {
    <li>{{ user.name }} — {{ user.email }}</li>
  } @empty {
    <li>No users found.</li>
  }
</ul>

<!-- Access loop variables -->
@for (item of items; track item.id; let i = $index, last = $last) {
  <div [class.last]="last">{{ i + 1 }}. {{ item.name }}</div>
}

@switch — Multiple Branches

@switch (status) {
  @case ('active') { <span class="green">Active</span> }
  @case ('pending') { <span class="yellow">Pending</span> }
  @default { <span class="gray">Inactive</span> }
}

@defer — Lazy Loading Blocks

<!-- Load HeavyComponent only when it enters the viewport -->
@defer (on viewport) {
  <app-heavy-component />
} @placeholder {
  <div>Loading...</div>
}
AngularJS {"id":64,"topic_id":33,"name":"Templates and Data Binding","slug":"templates-and-data-binding","image":null,"description":"<p>Master Angular's powerful template syntax \u2014 interpolation, property binding, event binding, and two-way binding.<\/p>","icon":null,"class":null,"color":null,"status":0,"order":2,"created_at":"2026-05-04T21:01:53.000000Z","updated_at":"2026-05-04T21:01:53.000000Z"} - List of Contents

Related Tutorials: