iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Use Angular’s @for block to render one piece of template content for each value in a collection. Add a required track expression—usually a unique, stable item property such as item.id—and place an optional @empty block after the loop to show a message when there are no items.
Write a basic @for loop
The loop has three parts: the item variable, the collection after of, and a required track expression. Put the repeated template between braces:
@for (item of items; track item.id) {
<li>{{ item.name }}</li>
}
Here, Angular renders an <li> for each value in items. The collection can be any JavaScript iterable; arrays also receive additional performance optimizations. See Angular’s @for API reference.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Choose a tracking expression that matches the collection
The track expression associates collection items with their rendered DOM views. That mapping helps Angular limit DOM operations when the collection changes. Choose a key based on whether it identifies the same item over time and whether the collection can be reordered or changed.
#1 Best Overall
| Tracking expression | Best fit | What to consider |
|---|---|---|
item.id (or another unique property) |
A collection whose items may be added, removed, updated, or reordered. | The property should uniquely identify each item and remain stable across updates. Angular recommends a unique property for dynamic collections. |
$index |
A collection that is truly static and does not change in membership or order. | It tracks a position, not an item identity. If items are inserted, removed, or reordered, positions no longer identify the same items. |
| Object reference | Usually not the best choice for collections that update. | Angular warns that tracking by object reference can make updates significantly slower because items are less directly mapped to DOM nodes. |
Track expressions can refer to $index, the loop item, and component-class properties or methods. An alias declared in the loop’s let segment can also be used. For details, see Angular’s control-flow guide.
Be aware of what happens when a tracked property changes
If the property used by track changes while the object reference stays the same, Angular updates bindings, including component inputs, rather than destroying and recreating the element. Angular documents this as a difference from *ngFor in the corresponding scenario.
Rank #2
Show an empty state and use loop variables
Put @empty immediately after the loop’s closing brace. Its content renders when the collection has no items. The loop also provides contextual values such as $index and $last; use let to give them shorter or clearer names.
Free tools Windows power users keep installed
One-click scans. No signup required.
@for (item of items; track item.id; let i = $index, last = $last) {
<li>{{ i }}: {{ item.name }}</li>
@if (last) {
<li>End of list</li>
}
} @empty {
<li>No items are available.</li>
}
The available contextual values are $count, $index, $first, $last, $even, and $odd. You can alias them through the let segment. For example, let i = $index makes the current index available as i.
Rank #3
Migrate from *ngFor and check your Angular version
Angular documents built-in control-flow syntax as available from v17. The current NgFor API marks NgFor deprecated since v20.0 and recommends @for; removal is intended in a future major release. The migration reference directs applications on v16 and older to the NgFor documentation, so check your project’s Angular version and version-specific guidance before changing templates.
- Run the migration schematic from your project’s workspace root:
ng generate @angular/core:control-flow - Review the converted templates. Confirm that each loop has an appropriate tracking expression and that any empty-state content is placed in an
@emptyblock after the loop. - Check imports and project behavior. Angular’s migration reference says built-in control flow is part of the template and no longer requires importing
CommonModulefor this functionality. Verify other template features and imports before removing shared imports.
Angular’s control-flow migration reference documents the schematic and migration context. Its control-flow tutorial directs applications using v16 and older to the NgFor documentation.
Rank #4
Account for the limits of @for
The @for block does not support JavaScript break or continue. If a loop should omit certain items, filter the collection in component logic or use conditional template content rather than trying to exit or skip an iteration with those statements.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

