ngFor
Deep dive into *ngFor — loop through arrays, access index and other variables, trackBy for performance.
ngFor
*ngFor repeats a template for each item in an array or iterable. It's the Angular equivalent of a for loop in the template.
Basic Syntax
<ul>
<li *ngFor="let fruit of fruits">{{ fruit }}</li>
</ul>
// component
fruits = ['Apple', 'Banana', 'Cherry', 'Date'];
Accessing the Index
<ul>
<li *ngFor="let item of items; let i = index">
{{ i + 1 }}. {{ item }}
</li>
</ul>
All Available Variables
| Variable | Type | Description |
|---|---|---|
index | number | Index of the current item (0-based) |
first | boolean | True if this is the first item |
last | boolean | True if this is the last item |
even | boolean | True if index is even |
odd | boolean | True if index is odd |
<div *ngFor="let user of users;
let i = index;
let isFirst = first;
let isLast = last;
let isEven = even">
<div class="user-row"
[class.first-row]="isFirst"
[class.last-row]="isLast"
[class.even-row]="isEven">
{{ i + 1 }}. {{ user.name }}
</div>
</div>
Looping Through Objects
// component
users = [
{ id: 1, name: 'Alice', role: 'Admin' },
{ id: 2, name: 'Bob', role: 'Developer' },
{ id: 3, name: 'Carol', role: 'Designer' },
];
// template
<div class="card" *ngFor="let user of users">
<h3>{{ user.name }}</h3>
<p>Role: {{ user.role }}</p>
<a [routerLink]="['/users', user.id]">View Profile</a>
</div>
Nested *ngFor
// component
categories = [
{ name: 'Frontend', skills: ['HTML', 'CSS', 'JavaScript'] },
{ name: 'Backend', skills: ['Node.js', 'Python', 'SQL'] },
];
// template
<div *ngFor="let category of categories">
<h3>{{ category.name }}</h3>
<ul>
<li *ngFor="let skill of category.skills">{{ skill }}</li>
</ul>
</div>
trackBy — Performance Optimization
<!-- Without trackBy, Angular re-renders ALL items when the array changes -->
<div *ngFor="let user of users; trackBy: trackByUserId">
{{ user.name }}
</div>
// component
trackByUserId(index: number, user: any): number {
return user.id; // Use unique id for tracking
}
trackBy tells Angular how to identify each item. Instead of destroying and recreating all DOM elements, it only updates what actually changed. Essential for large lists.
Combining *ngFor with *ngIf
<!-- Can't put both on the same element! Use ng-container: -->
<ng-container *ngFor="let user of users">
<div class="user-card" *ngIf="user.isActive">
{{ user.name }}
</div>
</ng-container>
<ng-container> is an Angular grouping element that doesn't render in the DOM — perfect for combining structural directives.
Key Takeaways
*ngFor="let item of items"loops through arrays- Access
index,first,last,even,oddlocal variables - Use
trackByfor performance with large or frequently-changing lists - Use
<ng-container>to combine*ngForwith*ngIfon the same level - Nested
*ngForworks for hierarchical data