Control Flow with @if, @for: Writing Angular Templates Like a Pro

Date: November 12, 2023

Angular 16 introduces exciting new syntax for control flow in templates — the directives @if and @for. These are designed to make template logic more readable and concise, improving developer experience while maintaining powerful reactive rendering capabilities.


Why the Change?

Until Angular 15, Angular templates primarily used structural directives like *ngIf and *ngFor for conditional rendering and loops:

<div *ngIf="isLoggedIn">Welcome back!</div>

<ul>
  <li *ngFor="let item of items">{{ item }}</li>
</ul>

While powerful, the * syntax sometimes felt verbose or limiting for more complex template logic. Angular 16’s @if and @for bring a cleaner, more intuitive approach inspired by modern reactive frameworks and templating languages.


Introducing @if

The new @if directive offers a more straightforward way to conditionally render content, using a block-style syntax:

@if (isLoggedIn) {
  <p>Welcome back, user!</p>
} else {
  <p>Please log in.</p>
}

Features:

  • Supports else and else if blocks naturally.
  • Improves readability by avoiding the repetition of multiple *ngIf and *ngIf else bindings.
  • Works seamlessly with Angular’s reactive change detection.

Comparison: *ngIf vs @if

<!-- Angular 15 and earlier -->
<div *ngIf="isLoggedIn; else loginPrompt">Welcome back!</div>
<ng-template #loginPrompt><p>Please log in.</p></ng-template>

<!-- Angular 16 -->
@if (isLoggedIn) {
  <p>Welcome back!</p>
} else {
  <p>Please log in.</p>
}

The new syntax reduces boilerplate and improves clarity.


Introducing @for

Looping with @for offers a similarly streamlined syntax for iterating over collections:

<ul>
  @for (let item of items) {
    <li>{{ item.name }} - {{ item.price | currency }}</li>
  }
</ul>

Features:

  • Supports index and last variables for iteration metadata.
  • Cleanly nests inside @if and other template expressions.
  • Aligns with common programming loop syntax, easing the learning curve.

Comparison: *ngFor vs @for

<!-- Angular 15 and earlier -->
<ul>
  <li *ngFor="let item of items; let i = index; let last = last">
    {{ i + 1 }}. {{ item.name }} ({{ item.price | currency }}) {{ last ? '(last item)' : '' }}
  </li>
</ul>

<!-- Angular 16 -->
<ul>
  @for (let item of items; let i = index; let last = last) {
    <li>{{ i + 1 }}. {{ item.name }} ({{ item.price | currency }}) {{ last ? '(last item)' : '' }}</li>
  }
</ul>

The @for block syntax makes it easier to include complex templates within loops without dealing with separate <ng-template> tags.


Mixing @if and @for

The new syntax allows for natural combination, improving template clarity:

@if (items.length > 0) {
  <ul>
    @for (let item of items) {
      <li>{{ item.name }}</li>
    }
  </ul>
} else {
  <p>No items found.</p>
}

Backwards Compatibility

The @if and @for directives are fully compatible with existing Angular features and tooling. They compile down to the same efficient instructions Angular uses today, so no performance trade-offs occur.


Summary

  • Angular 16 introduces @if and @for for clearer, more concise template control flow.
  • These new directives reduce boilerplate and improve readability.
  • They align with common programming patterns, easing adoption.
  • Backward compatibility is preserved, allowing gradual adoption.

Ready to try?

Update your Angular 16 project and start refactoring templates to embrace @if and @for for cleaner, more maintainable code!


Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

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