I’ve been using Angular for quite some time, and like many developers, I got used to writing *ngIf, *ngFor, and ngSwitch in almost every component. They worked fine until Angular introduced a new syntax that completely changed how I write templates.
I’m talking about the new control flow syntax:
@if, @else, @for, @let, @switch, @case, and @default.
At first, I didn’t pay much attention. But after giving them a try, I quickly realized how much cleaner, simpler, and more natural my templates became.
Here’s why I stopped using the old syntax and why you might want to as well.
The Problem with the Old Syntax
The old *ngIf, *ngFor, and ngSwitch directives worked well, but they had a few downsides:
The asterisks
*looked strange to new developers.You often needed extra
<ng-container>or<ng-template>tags.Nested conditions and loops were harder to read.
Angular’s new syntax fixes all of that. It’s built directly into the template engine, meaning no more directives — just clean, readable control flow.
@if and @else
The new @if syntax replaces *ngIf and feels much closer to regular JavaScript logic.
Before:
<div *ngIf="isLoggedIn; else guestPart">
Welcome back!
</div>
<ng-template #guestPart>
Please log in.
</ng-template>
Now:
@if (isLoggedIn) {
<div>Welcome back!</div>
} @else {
<div>Please log in.</div>
}
✅ Easier to read
✅ No blocks or template references
✅ Perfect for nesting conditions
@for
The classic *ngFor still works, but @for feels cleaner and reads more like plain JavaScript.
Before:
<ul>
<li *ngFor="let user of users; trackBy: trackById">
{{ user.name }}
</li>
</ul>
Now:
<ul>
@for (user of users; track user.id) {
<li>{{ user.name }}</li>
}
</ul>
✅ Simpler syntax (track instead of trackBy)
✅ No asterisk confusion
✅ Easier to reason about
@let
Sometimes you need to store a local variable in your template.
@let makes that super easy.
Before:
<ng-container *ngIf="user as u">
<p>Hello {{ u.name }}</p>
</ng-container>
Now:
@let u = user;
<p>Hello {{ u.name }}</p>
✅ Cleaner variable handling
✅ Works outside @if blocks
✅ Makes templates easier to follow
@switch, @case, and @default
The new @switch syntax replaces ngSwitch and feels just like a real switch statement in JavaScript.
Before:
<div [ngSwitch]="status">
<p *ngSwitchCase="'active'">Active</p>
<p *ngSwitchCase="'inactive'">Inactive</p>
<p *ngSwitchDefault>Unknown</p>
</div>
Now:
@switch (status) {
@case ('active') {
<p>Active</p>
}
@case ('inactive') {
<p>Inactive</p>
}
@default {
<p>Unknown</p>
}
}
✅ More readable
✅ No extra attributes
✅ Matches JavaScript logic perfectly
How to Start Using It
You’ll need Angular 17 or newer to use this new syntax.
If you’re upgrading, just run:
ng update @angular/core@latest @angular/cli@latest
No extra setup or imports needed — it’s ready out of the box.
Final Thoughts
After switching to the new syntax, my templates feel much cleaner and easier to maintain.
I don’t need to wrap everything in containers or remember special * rules anymore.
If you’ve been using Angular for a while, try replacing a few *ngIf or *ngFor blocks with the new syntax and you’ll instantly see the difference.
Sometimes small changes make a big impact and this one definitely does.
Top comments (0)