
If you’re still using the classic *ngFor
directive, it’s a good time to look into Angular’s newer, cleaner way to loop through data β the @for
block. Not only is it easier to read, but it also performs better and feels more like the modern frameworks we all admire (hello React and Svelte π).
β¨ Whatβs New in Angular’s Template Syntax?
Angular introduced a new set of control flow blocks:
@if
@for
@switch
These are part of Angularβs push toward simpler, more readable templates that compile faster thanks to the new template engine.
π Say Hello to @for
Hereβs what looping looks like now:
@for (item of items; track item.id) {
<div>{{ item.name }}</div>
}
Why itβs better:
- No more
*
symbols cluttering the template - Feels like a real
for
loop track
is built-in β no need for a separatetrackBy
function
π Built-In Context Variables
Just like *ngFor
, @for
gives you context-aware variables:
@for (item of items; track item.id; let i = $index; let isFirst = $first; let isLast = $last) {
<div>
{{ i + 1 }}. {{ item.name }}
<span *ngIf="isFirst">π First</span>
<span *ngIf="isLast">π₯ Last</span>
</div>
}
Quick reference:
$index
: current index$first
: true for the first item$last
: true for the last item$even
,$odd
: for alternating styles
π§ Why track
is Better than trackBy
Old way with *ngFor
:
trackByFn(index: number, item: Item) {
return item.id;
}
New way with @for
:
@for (item of items; track item.id) {
<div>{{ item.name }}</div>
}
Bonus:
- Less boilerplate
- Keeps logic in the template
- Better performance
π§ Real Use Case
items = [
{ id: 1, name: 'Angular' },
{ id: 2, name: 'React' },
{ id: 3, name: 'Vue' },
];
@for (item of items; track item.id; let i = $index) {
<p>{{ i + 1 }} - {{ item.name }}</p>
}
Looks cleaner, works smarter.
π§© Combine with @if
@for (product of products; track product.id) {
@if (product.inStock) {
<app-product-card [product]="product"></app-product-card>
}
}
No more messy *ngIf
inside *ngFor
. Itβs readable and structured.
β Final Thoughts: Why I Made the Switch
Switching from *ngFor
to @for
was a no-brainer once I tried it. Hereβs why:
- Cleaner, easier-to-read templates
- Better performance thanks to inline tracking
- More modern, declarative approach
- Plays nicely with signals and the latest Angular features
If youβre on Angular 17 or newer, give it a shot. Youβll be glad you did.