Angular’s *ngFor
directive is a powerful structural directive used to dynamically render elements for each item in a collection. It is fundamental for building dynamic lists, tables, menus, and other repetitive UI elements.
This guide covers:
- Introduction to
*ngFor
- Basic syntax and usage
- Iterating over arrays
- Using index and first/last flags
- Nested
*ngFor
loops - Rendering objects and key-value pairs
- Combining
*ngFor
with other directives - Dynamic lists with events
- Performance considerations and best practices
- Summary
1. Introduction to *ngFor
*ngFor
is an Angular structural directive that adds or removes DOM elements based on an array or collection in the component.
- Dynamic rendering: Automatically updates the DOM when the collection changes.
- Reusable patterns: Can render lists, tables, dropdowns, and grids.
- Template-driven: Works seamlessly with Angular templates and property binding.
2. Basic Syntax and Usage
The basic syntax of *ngFor
:
<li *ngFor="let item of items">{{ item }}</li>
let item of items
iterates over the arrayitems
.item
represents the current element in the iteration.- The element is created for each array item.
Example
// component.ts
products = ['Laptop', 'Phone', 'Tablet'];
<ul>
<li *ngFor="let product of products">{{ product }}</li>
</ul>
- Renders three list items for Laptop, Phone, and Tablet.
3. Iterating Over Arrays
*ngFor
works with arrays of primitives or objects.
3.1 Array of Strings
categories = ['Electronics', 'Clothing', 'Books'];
<ul>
<li *ngFor="let category of categories">{{ category }}</li>
</ul>
3.2 Array of Objects
products = [
{ name: 'Laptop', price: 1200 },
{ name: 'Phone', price: 800 },
{ name: 'Tablet', price: 600 }
];
<ul>
<li *ngFor="let product of products">
{{ product.name }} - ${{ product.price }}
</li>
</ul>
- Access properties of each object using
item.property
.
4. Using Index and First/Last Flags
Angular provides local variables inside *ngFor
:
index
→ current iteration indexfirst
→ true if first itemlast
→ true if last itemeven
/odd
→ boolean flags for even/odd items
Example
<ul>
<li *ngFor="let product of products; let i = index; let first = first; let last = last; let even = even">
{{ i + 1 }}. {{ product.name }}
<span *ngIf="first">- First Item</span>
<span *ngIf="last">- Last Item</span>
<span *ngIf="even">- Even</span>
</li>
</ul>
- Provides enhanced context about the loop iteration.
- Useful for conditional styling or labels.
5. Nested *ngFor Loops
You can use *ngFor
inside another *ngFor
to render nested collections.
Example: Categories with Products
categories = [
{ name: 'Electronics', items: ['Laptop', 'Phone'] },
{ name: 'Books', items: ['Novel', 'Comics'] }
];
<div *ngFor="let category of categories">
<h3>{{ category.name }}</h3>
<ul>
<li *ngFor="let item of category.items">{{ item }}</li>
</ul>
</div>
- Outer loop renders categories.
- Inner loop renders products within each category.
6. Rendering Objects and Key-Value Pairs
Angular can iterate over object entries using keyvalue
pipe.
Example: Object Iteration
user = { name: 'John', age: 30, email: '[email protected]' };
<ul>
<li *ngFor="let item of user | keyvalue">
{{ item.key }}: {{ item.value }}
</li>
</ul>
- Renders all key-value pairs dynamically.
7. Combining *ngFor with Other Directives
*ngFor
can be combined with:
*ngIf
for conditional rendering[ngClass]
and[ngStyle]
for dynamic styles
Example: Highlight Expensive Products
<ul>
<li *ngFor="let product of products" [ngClass]="{'expensive': product.price > 1000}">
{{ product.name }} - ${{ product.price }}
</li>
</ul>
.expensive { font-weight: bold; color: red; }
- Highlights items based on a condition dynamically.
8. Dynamic Lists with Events
*ngFor
works well with event binding, enabling interactive lists.
Example: Delete Item from List
products = ['Laptop', 'Phone', 'Tablet'];
deleteProduct(product: string) {
this.products = this.products.filter(p => p !== product);
}
<ul>
<li *ngFor="let product of products">
{{ product }}
<button (click)="deleteProduct(product)">Delete</button>
</li>
</ul>
- Clicking delete removes the item dynamically.
- Angular updates the DOM automatically.
9. Performance Considerations and Best Practices
9.1 Use TrackBy
Angular re-renders lists on change by default. Use trackBy
for large lists:
<li *ngFor="let product of products; trackBy: trackByFn">
{{ product.name }}
</li>
trackByFn(index: number, product: any) {
return product.id; // unique identifier
}
- Improves performance by reusing existing DOM elements.
9.2 Avoid Nested Loops for Large Data
- Nested
*ngFor
can cause performance issues for large collections. - Consider flattening data or using virtual scrolling.
9.3 Use Pipes for Filtering/Sorting
- Filter or sort arrays before binding, or use Angular custom pipes.
<li *ngFor="let product of products | filter: searchText">{{ product.name }}</li>
10. Summary
*ngFor
is an essential Angular directive for:
- Iterating over arrays and objects
- Creating dynamic lists and tables
- Accessing contextual variables like
index
,first
,last
- Nesting loops for complex structures
- Combining with events, pipes, and directives for interactive UIs
- Optimizing performance with
trackBy
It forms the backbone of dynamic template rendering in Angular applications, making it a critical tool for developers building modern web applications.
Combined Example: Dynamic Product List
products = [
{ id: 1, name: 'Laptop', price: 1200 },
{ id: 2, name: 'Phone', price: 800 },
{ id: 3, name: 'Tablet', price: 600 }
];
deleteProduct(product: any) {
this.products = this.products.filter(p => p.id !== product.id);
}
<ul>
<li *ngFor="let product of products; trackBy: trackByFn" [ngClass]="{'expensive': product.price > 1000}">
{{ product.name }} - ${{ product.price }}
<button (click)="deleteProduct(product)">Delete</button>
</li>
</ul>
trackByFn(index: number, product: any) {
return product.id;
}
- Demonstrates dynamic rendering, styling, deletion, and performance optimization with
*ngFor
.
Leave a Reply