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
andelse 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
andlast
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!