Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

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.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
@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.

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.

  1. Run the migration schematic from your project’s workspace root:
    ng generate @angular/core:control-flow
  2. Review the converted templates. Confirm that each loop has an appropriate tracking expression and that any empty-state content is placed in an @empty block after the loop.
  3. Check imports and project behavior. Angular’s migration reference says built-in control flow is part of the template and no longer requires importing CommonModule for 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.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.