The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →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
Angular error NG0956 means an @for loop’s track expression made Angular recreate the DOM for every item. If an update replaces list objects with new instances, track a stable, unique property such as todo.id instead of the object itself. Use $index only when the collection’s items and positions stay static.
What NG0956 means
An @for block uses its track expression to associate collection items with their rendered views. As items are added, removed, or moved, Angular uses those keys to determine which DOM views can be reused. The key should represent the logical identity of an item, not merely its current object instance. Angular’s @for API describes the tracking value as the key used to associate array items with DOM views.
NG0956 occurs when the chosen key makes Angular treat every item as new. The list may still display the right data, but Angular throws away and rebuilds its views instead of updating the existing ones. Angular’s NG0956 documentation calls this a very expensive operation, but does not quantify its performance impact.
Why tracking an object can recreate every row
Suppose the template tracks each todo object directly:
#1 Best Overall
@for (todo of todos; track todo) {
<li>{{ todo.task }}</li>
}
This key is the object’s identity. An immutable update that creates replacement objects changes that identity, even if each replacement represents the same todo:
this.todos = this.todos.map(todo => ({ ...todo, done: true }));
After this update, Angular sees new object references. With track todo, it can treat all the rows as new and recreate them, although the logical records remain the same and only a property needs updating.
Rank #2
Fix NG0956 with a stable, unique key
Track a property that uniquely identifies each logical item and remains the same when its object is refreshed or reconstructed. For example, if every todo has a stable, unique id, change the loop to:
@for (todo of todos; track todo.id) {
<li>{{ todo.task }}</li>
}
Angular can then match each new object to the existing view for the same todo. Choose a key that meets these checks:
Rank #3
- It is unique among the items in the collection.
- It stays stable for the lifetime of the logical item.
- It is preserved when the data is refreshed or recreated.
If the data has no suitable unique property, decide how the application should identify the same logical record across updates before choosing a tracking expression. An unstable or duplicate key cannot reliably preserve the correct association.
When to use $index
track $index uses an item’s position as its key. Angular documents this as suitable for a collection that remains static. It is not a general fix for NG0956: when items are inserted, removed, or reordered, a position can refer to a different item, so it does not reliably express item identity. For changing collections, use a stable, unique item property instead. See Angular’s @for API guidance.
Rank #4
Why DOM re-creation matters
Rebuilding a row can discard state held by its DOM elements. Angular specifically notes that this can affect focus, text selection, and sites loaded in an iframe. A stable key lets Angular preserve the association between a logical item and its existing view when the item’s data changes.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →If the component still uses *ngFor
The older NgFor directive provides a trackBy function for identifying items when object instances change. Angular’s NgFor API says the directive has been deprecated since Angular v20.0 and recommends using @for instead. Check the Angular version used by the project when planning any migration; for current @for code, put the stable key directly in the track expression.
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.

