Angular 17 introduced a new built-in control flow syntax directly in templates — replacing the older *ngIf, *ngFor, and *ngSwitch structural directives.
<!-- 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>
<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 (status) {
@case ('active') { <span class="green">Active</span> }
@case ('pending') { <span class="yellow">Pending</span> }
@default { <span class="gray">Inactive</span> }
}
<!-- Load HeavyComponent only when it enters the viewport -->
@defer (on viewport) {
<app-heavy-component />
} @placeholder {
<div>Loading...</div>
}