Angular v17+ introduced modern control flow syntax such as @if and @for, which provide a cleaner, more intuitive alternative to traditional *ngIf and *ngFor. These new blocks also offer improved TypeScript support and powerful contextual variables for more control inside templates.
@if – Template block for conditional rendering (replaces *ngIf).@else and @else if – Handle alternative conditions in a readable way.@for – Looping construct with better syntax than *ngFor.track – Optimizes list rendering by tracking items efficiently.$index, $first, $last, $count, etc.The @if block evaluates a condition and renders the content only when it is true. You can combine it with @else and @else if for multiple branches, similar to standard if / else if / else in TypeScript.
// app.component.ts
export class AppComponent {
isLoggedIn = true;
}
<!-- app.component.html: Conditional welcome message using @if -->
@if (isLoggedIn) {
<p>Welcome back, user!</p>
} @else {
<p>Please log in.</p>
}
Here, @if (isLoggedIn) checks the component property isLoggedIn. When it is true, the user sees “Welcome back, user!”. Otherwise, the @else block runs and shows “Please log in.”.
This is easier to read than the structural directive form *ngIf="isLoggedIn; else elseBlock", and it behaves closer to regular TypeScript control flow.
The @for block is a modern replacement for *ngFor. It offers:
track for performance.$index and $count.
// app.component.ts
export class AppComponent {
fruits = ['Apple', 'Banana', 'Cherry'];
}
<!-- app.component.html: Looping with @for and contextual variables -->
@for (fruit of fruits; track fruit; let i = $index) {
<p>{{ i + 1 }}. {{ fruit }}</p>
}
The @for loop runs over the fruits array and renders one <p> tag for each fruit. In this example:
fruit – The current item in the array.track fruit – Uses the fruit value itself as the tracking key.$index – Gives the current zero-based index (we display it as i + 1).Other useful contextual variables include:
$first → true for the first item in the list.$last → true for the last item in the list.$count → The total number of items.You will often combine @if and @for to render lists only when data exists. This keeps templates robust and avoids empty or broken views when arrays are empty.
// app.component.ts
export class AppComponent {
fruits = ['Apple', 'Banana', 'Cherry'];
showList = true;
}
<!-- app.component.html: Showing list only when showList is true -->
@if (showList) {
<h3>Fruit List</h3>
@for (fruit of fruits; let i = $index) {
<p>{{ i + 1 }}. {{ fruit }}</p>
}
} @else {
<p>No fruits available.</p>
}
Case 1: showList = true
Case 2: showList = false
The template shows: No fruits available.
@if over *ngIf in Angular 17+ projects for cleaner, more readable templates.@for with track when rendering lists to avoid unnecessary DOM re-renders.$index, $first, $last, and $count for UI enhancements (badges, separators, highlighting).@if and @for.*ngIf/*ngFor with @if/@for in the same codebase unless migrating gradually.@if and @else to show different messages for logged-in and guest users.@for:
$first and the last element using $last.@if to check if products exist before looping.@for to render the products and show the total count using $count.