Bird
Raised Fist0
Angularframework~10 mins

TrackBy in ngFor in Angular - Step-by-Step Execution

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Concept Flow - TrackBy in ngFor
Start ngFor loop
Render list items
Detect changes in list
Use TrackBy function?
NoRe-render all items
Yes
Compare items by TrackBy key
Update only changed items
Render updated list
This flow shows how Angular's ngFor uses TrackBy to optimize rendering by tracking items with a unique key, updating only changed items.
Execution Sample
Angular
items = [{id:1, name:'A'}, {id:2, name:'B'}];

trackById(index, item) {
  return item.id;
}

// In template:
// *ngFor="let item of items; trackBy: trackById"
This code loops over items and uses trackById to identify each item by its unique id.
Execution Table
StepActionOld ListNew ListTrackBy Key UsedItems UpdatedRendered Output
1Initial render[][{id:1,name:'A'},{id:2,name:'B'}]N/AAll itemsA, B
2Update list with new object but same ids[{id:1,name:'A'},{id:2,name:'B'}][{id:1,name:'A1'},{id:2,name:'B'}]idOnly item with id=1A1, B
3Update list with new item added[{id:1,name:'A1'},{id:2,name:'B'}][{id:1,name:'A1'},{id:2,name:'B'},{id:3,name:'C'}]idNew item with id=3A1, B, C
4Remove item with id=2[{id:1,name:'A1'},{id:2,name:'B'},{id:3,name:'C'}][{id:1,name:'A1'},{id:3,name:'C'}]idRemoved item with id=2A1, C
5Update list with same objects but different order[{id:1,name:'A1'},{id:3,name:'C'}][{id:3,name:'C'},{id:1,name:'A1'}]idNo items updated, only order changedC, A1
6Update list with new objects without trackBy[{id:3,name:'C'},{id:1,name:'A1'}][{id:3,name:'C'},{id:1,name:'A1'}]No trackByAll items re-renderedC, A1
💡 Rendering stops after list updates and Angular applies trackBy to optimize DOM updates.
Variable Tracker
VariableStartAfter 1After 2After 3After 4After 5After 6
items[][{id:1,name:'A'},{id:2,name:'B'}][{id:1,name:'A1'},{id:2,name:'B'}][{id:1,name:'A1'},{id:2,name:'B'},{id:3,name:'C'}][{id:1,name:'A1'},{id:3,name:'C'}][{id:3,name:'C'},{id:1,name:'A1'}][{id:3,name:'C'},{id:1,name:'A1'}]
trackByKeyN/A[1,2][1,2][1,2,3][1,3][3,1]N/A
Key Moments - 3 Insights
Why does Angular re-render all items if trackBy is not used?
Without trackBy, Angular compares items by object reference, so new objects cause full re-render (see step 6 in execution_table).
How does trackBy help when item order changes but items are the same?
TrackBy uses unique keys to detect same items despite order change, so Angular only updates order without re-rendering items (see step 5).
What happens if trackBy returns a non-unique key?
Angular may confuse items and update wrong elements, causing rendering bugs. Keys must be unique (implied in execution_table keys).
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, at which step does Angular update only one item instead of all?
AStep 4
BStep 2
CStep 6
DStep 1
💡 Hint
Check the 'Items Updated' column for step 2 and step 6.
According to variable_tracker, what is the trackByKey after step 3?
A[1,2]
B[1,3]
C[1,2,3]
D[3,1]
💡 Hint
Look at the 'trackByKey' row under 'After 3' column.
If trackBy was removed, what would happen at step 6 according to the execution table?
AAll items re-rendered
BNo items update
COnly new items update
DOnly order changes
💡 Hint
See the 'Items Updated' and 'TrackBy Key Used' columns at step 6.
Concept Snapshot
TrackBy in ngFor:
- Use trackBy to give each item a unique key.
- Angular uses this key to track items efficiently.
- Without trackBy, Angular re-renders all items on change.
- TrackBy improves performance by updating only changed items.
- Syntax: *ngFor="let item of items; trackBy: trackByFn"
Full Transcript
TrackBy in Angular's ngFor helps Angular identify list items uniquely during rendering. When the list changes, Angular uses the trackBy function to compare items by their unique keys instead of object references. This allows Angular to update only the changed items in the DOM, improving performance. Without trackBy, Angular re-renders all items whenever the list changes, even if only one item changed. The execution table shows how Angular updates items step-by-step using trackBy keys. The variable tracker shows how the list and keys change over time. Key moments clarify why trackBy is important and how it handles item order changes. The visual quiz tests understanding of these concepts by referencing the execution visuals.

Practice

(1/5)
1. What is the main purpose of using trackBy in an ngFor directive in Angular?
easy
A. To improve performance by uniquely identifying list items during updates
B. To style list items differently based on their index
C. To sort the list items before rendering
D. To filter out duplicate items from the list

Solution

  1. Step 1: Understand what ngFor does

    ngFor repeats a template for each item in a list, rendering them in the view.
  2. Step 2: Identify the role of trackBy

    trackBy helps Angular know which items changed by uniquely identifying them, so it only updates those items instead of re-rendering the whole list.
  3. Final Answer:

    To improve performance by uniquely identifying list items during updates -> Option A
  4. Quick Check:

    TrackBy improves performance = C [OK]
Hint: TrackBy helps Angular track items uniquely for faster updates [OK]
Common Mistakes:
  • Thinking trackBy sorts or filters items
  • Believing trackBy changes item styles
  • Assuming trackBy removes duplicates
2. Which of the following is the correct syntax to use trackBy in an ngFor loop?
easy
A. *ngFor="let item of items; trackByFn"
B. *ngFor="let item of items; trackBy: trackByFn"
C. *ngFor="let item of items; trackByFn()"
D. *ngFor="let item of items; trackBy=trackByFn()"

Solution

  1. Step 1: Recall the correct ngFor syntax with trackBy

    The correct syntax uses a semicolon and the keyword trackBy followed by the function name without parentheses.
  2. Step 2: Compare options

    *ngFor="let item of items; trackBy: trackByFn" matches the correct syntax: *ngFor="let item of items; trackBy: trackByFn". Others either miss the keyword or use parentheses incorrectly.
  3. Final Answer:

    *ngFor="let item of items; trackBy: trackByFn" -> Option B
  4. Quick Check:

    Correct syntax includes 'trackBy:' keyword [OK]
Hint: Use 'trackBy:' keyword with function name, no parentheses [OK]
Common Mistakes:
  • Omitting 'trackBy:' keyword
  • Adding parentheses after function name
  • Using '=' instead of ':'
3. Given the component code below, what will be logged when the items array is updated by adding a new item?
items = [{id: 1, name: 'A'}, {id: 2, name: 'B'}];

trackByFn(index: number, item: any) {
  return item.id;
}

Template:
<div *ngFor="let item of items; trackBy: trackByFn">{{item.name}}</div>
medium
A. Rendering throws an error due to trackBy function
B. All items are re-rendered and logged
C. No items are rendered
D. Only the new item is rendered and logged

Solution

  1. Step 1: Understand how trackBy works with unique IDs

    The trackByFn returns the unique id of each item, so Angular can track items by their IDs.
  2. Step 2: Effect of adding a new item

    When a new item is added, Angular uses trackByFn to detect only the new item and renders just that one, not the entire list.
  3. Final Answer:

    Only the new item is rendered and logged -> Option D
  4. Quick Check:

    trackBy with unique ID renders only changed items [OK]
Hint: trackBy returns unique id to render only changed items [OK]
Common Mistakes:
  • Assuming all items re-render on update
  • Thinking trackBy causes errors if function returns id
  • Believing no items render after update
4. Identify the error in the following trackBy function used in an ngFor loop:
trackByFn(index: number, item: any) {
  return index + 1;
}
medium
A. It returns a non-unique value causing incorrect tracking
B. It returns the index which is acceptable and error-free
C. It throws a syntax error due to missing return type
D. It causes Angular to ignore the trackBy function

Solution

  1. Step 1: Analyze the returned value from trackByFn

    The function returns index + 1, which changes if the list order changes or items are added/removed.
  2. Step 2: Understand why this causes problems

    Returning a value based on index is not stable for tracking because indexes shift, causing Angular to think items changed incorrectly.
  3. Final Answer:

    It returns a non-unique value causing incorrect tracking -> Option A
  4. Quick Check:

    trackBy must return stable unique IDs, not shifting indexes [OK]
Hint: trackBy must return stable unique IDs, not changing indexes [OK]
Common Mistakes:
  • Thinking index is always safe to return
  • Ignoring that indexes shift on list changes
  • Assuming missing return type causes syntax error
5. You have a list of users with possible duplicate names but unique IDs. You want to optimize rendering with trackBy. Which trackBy function below correctly handles this scenario to avoid unnecessary re-renders when the list updates?
hard
A. trackByFn(index: number, user: any) { return user.name; }
B. trackByFn(index: number, user: any) { return index; }
C. trackByFn(index: number, user: any) { return user.id; }
D. trackByFn(index: number, user: any) { return user; }

Solution

  1. Step 1: Identify the unique property for tracking

    Users may have duplicate names, so using user.name is not reliable. The unique user.id is the best choice.
  2. Step 2: Evaluate each option

    A uses user.name (not unique), B uses user.id (stable and unique), C uses index (unstable), D returns the whole user object (not recommended).
  3. Final Answer:

    trackByFn(index: number, user: any) { return user.id; } -> Option C
  4. Quick Check:

    Use unique IDs for trackBy to avoid re-renders [OK]
Hint: Always trackBy unique stable IDs, not names or indexes [OK]
Common Mistakes:
  • Using non-unique properties like names
  • Using index which changes on list updates
  • Returning the whole object causing errors