Angular Components Created: 06 Jan 2026 Updated: 06 Jan 2026

FOR Control Block

1. Preparing the Data Model

First, let's update our component with a list of speakers. We will use a Speaker interface to maintain type safety.

speaker-list.component.ts

TypeScript


export interface Speaker {
id: number;
name: string;
topic: string;
}

@Component({
selector: 'app-speaker-list',
standalone: true,
templateUrl: './speaker-list.component.html',
styleUrl: './speaker-list.component.css'
})
export class SpeakerListComponent {
speakers: Speaker[] = [
{ id: 101, name: 'Alice Freeman', topic: 'Microservices Architecture' },
{ id: 102, name: 'Bob Smith', topic: 'Angular Signals Deep Dive' },
{ id: 103, name: 'Catherine Low', topic: 'Cloud-Native .NET' }
];
}

2. Rendering Lists with @for

The @for block is essentially the JavaScript for...of loop tailored for HTML. It allows you to define a placeholder for each item and render a template for it.

speaker-list.component.html

HTML


<ul class="speaker-group">
@for (speaker of speakers; track speaker.id) {
<li class="speaker-card">
<strong>{{ speaker.name }}</strong> - {{ speaker.topic }}
</li>
}
</ul>

Why is track mandatory?

In the new @for block, the track property is required. It tells Angular which unique property (like an id) it should use to identify each item.

  1. Performance: If the list changes, Angular only re-renders the items that actually changed rather than the entire list.
  2. DOM Stability: It prevents losing focus or state in input fields within a list when the array is updated.

3. Handling Empty States with @empty

In the past, we had to use an extra *ngIf to check if a list was empty. Now, the @for block comes with a built-in @empty section that renders automatically when the array length is zero.

HTML


<div class="container">
@if (speakers.length > 0) {
<h1>Conference Speakers ({{ speakers.length }})</h1>
}

<div class="list-wrapper">
@for (s of speakers; track s.id) {
<div class="card">{{ s.name }}</div>
}
@empty {
<p class="alert">No speakers have been registered for this event yet.</p>
}
</div>
</div>

4. Using Contextual Variables

Angular provides several "helper" variables within the loop to give you more control over the UI, such as indexing or identifying the first/last items.

  1. $index: Current item index.
  2. $count: Total number of items.
  3. $first / $last: Boolean for the first or last item.
  4. $even / $odd: Boolean for even or odd rows (perfect for zebra-striping).

Example using aliases:

HTML


@for (s of speakers; track s.id; let i = $index; let total = $count) {
<div class="row">
<span>#{{ i + 1 }} of {{ total }}</span>
<h3>{{ s.name }}</h3>
</div>
}

5. Modern @for vs. Legacy *ngFor

If you are coming from an older Angular project, you might be familiar with *ngFor. Here is why the new syntax is superior:

FeatureLegacy *ngForModern @for
SyntaxMicro-syntax string: *ngFor="..."Built-in block: @for (...) { }
PerformanceOptional trackBy functionRequired track (Optimized by default)
Empty StateRequires separate *ngIfBuilt-in @empty block
ImportsRequires CommonModuleBuilt-in (No imports needed in Standalone)


Share this lesson: