Angular 20 has officially said goodbye to the classic structural directives like *ngIf
, *ngFor
, and *ngSwitch
. These have been replaced with a modern control-flow syntax that looks and feels closer to JavaScript and TypeScript.
In this blog, we’ll explore the new Angular 20 HTML syntaxes, explain how they work, and show migration examples to help you adapt quickly.
Why the Change?
For years, Angular used structural directives (*ngIf
, *ngFor
, *ngSwitch
) to control the DOM. While powerful, they had limitations:
- Syntax was different from standard JS/TS.
- Required
*
prefix and hiddenng-template
wrapping. - Less readable for complex templates.
The new block-style control flow fixes this by making Angular templates feel more like writing plain code.
1. Conditional Rendering with @if
Old Way (Deprecated):
<div *ngIf="isLoggedIn; else guest">
Welcome back, {{ userName }}!
</div>
<ng-template #guest>
<p>Please log in</p>
</ng-template>
New Way (Angular 20+):
@if (isLoggedIn) {
<div>Welcome back, {{ userName }}!</div>
} @else {
<p>Please log in</p>
}
- Cleaner syntax.
- No need for extra .
- Supports else if for multiple conditions.
2. Looping with @for
Old Way (Deprecated):
<ul>
<li *ngFor="let item of items; index as i; trackBy: trackByFn">
{{ i+1 }}. {{ item }}
</li>
</ul>
New Way (Angular 20+):
<ul>
@for (item of items; track trackByFn(item); let i = $index) {
<li>{{ i+1 }}. {{ item }}</li>
}
</ul>
- Uses block syntax, similar to for-of loops.
- Built-in $index, $count, $first, $last.
- track replaces trackBy with a more natural function call.
3. Switch Cases with @switch
Old Way (Deprecated):
<div [ngSwitch]="role">
<p *ngSwitchCase="'admin'">Admin Access</p>
<p *ngSwitchCase="'user'">User Access</p>
<p *ngSwitchDefault>Guest Access</p>
</div>
New Way (Angular 20+):
@switch (role) {
@case ('admin') {
<p>Admin Access</p>
}
@case ('user') {
<p>User Access</p>
}
@default {
<p>Guest Access</p>
}
}
- Clear structure.
- Looks like a real switch statement.
- Easier to manage multiple cases.
4. Migration Made Easy
Angular provides a migration tool to automatically update your templates:
ng update @angular/core --name=control-flow-migration
This will replace deprecated syntaxes (*ngIf
, *ngFor
, *ngSwitch
) with their modern counter parts.
5. Example: Full Component in Angular 20
Here’s a simple component template using all new syntaxes:
<h1>User Dashboard</h1>
@if (isLoggedIn) {
<p>Welcome, {{ userName }}</p>
<ul>
@for (task of tasks; let i = $index) {
<li>{{ i+1 }}. {{ task }}</li>
}
</ul>
@switch (role) {
@case ('admin') {
<button>Manage Users</button>
}
@case ('editor') {
<button>Edit Content</button>
}
@default {
<p>Basic User Access</p>
}
}
} @else {
<p>Please log in to access your dashboard.</p>
}
Key Benefits of the New Syntax
- Cleaner & Readable → Closer to plain TypeScript.
- No More * Prefix → No hidden ng-template wrappers.
- Better Tooling → Stronger compiler diagnostics and editor support.
- Future-Proof → Old syntax is deprecated, this is the new standard.
Top comments (0)