πŸ” Upgrading *ngFor: Why I Switched to @for in Angular

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 separate trackBy 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.

Leave a Comment

Your email address will not be published. Required fields are marked *