When you build Angular applications, you will often display lists of data, show or hide elements, or conditionally render UI blocks.
Two of the most commonly used structural directives for this are:
This guide teaches both with simple examples, best practices, and real-world use cases.
1. What Are Structural Directives?
Structural directives change the DOM structure by adding or removing elements.
Angular provides three main structural directives:
| Directive | Purpose |
|---|
*ngIf | Conditionally render elements |
*ngFor | Loop and display lists |
*ngSwitch | Multi-condition rendering |
In this article, we focus on ngFor and ngIf.
2. Using *ngFor to Loop and Display Data
ngFor is used when you want to render a list (array) of items.
Example: Display a list of users
TypeScript (component.ts)
users = [
{ id: 1, name: 'Rajesh' },
{ id: 2, name: 'Mohan' },
{ id: 3, name: 'Priya' }
];
HTML (component.html)
<ul>
<li *ngFor="let user of users">
{{ user.name }}
</li>
</ul>
✔ Angular repeats <li> for every user in the array.
3. Advanced ngFor Features
Get index of each item
<li *ngFor="let user of users; let i = index">
{{ i + 1 }}. {{ user.name }}
</li>
Check if item is first or last
<div *ngFor="let user of users; let isFirst = first; let isLast = last">
<span *ngIf="isFirst">🌟 First User → </span>
<span *ngIf="isLast">🏁 Last User → </span>
{{ user.name }}
</div>
Track items for performance
<li *ngFor="let user of users; trackBy: trackById">
{{ user.name }}
</li>
trackById(index: number, user: any) {
return user.id;
}
✔ Helps avoid re-rendering when working with large lists.
4. Using *ngIf to Show or Hide Elements
ngIf adds or removes an element from the DOM based on a condition.
Example: Show message when users list is empty
<p *ngIf="users.length === 0">No users found.</p>
Example: Show a loading message
<p *ngIf="isLoading">Loading...</p>
ngIf with else block
<div *ngIf="isLoggedIn; else notLogged">
Welcome back!
</div>
<ng-template #notLogged>
<p>Please log in.</p>
</ng-template>
5. Combining *ngFor and *ngIf (Real Examples)
Example 1: Show list only if data exists
<div *ngIf="users.length > 0; else noData">
<li *ngFor="let user of users">{{ user.name }}</li>
</div>
<ng-template #noData>
<p>No users available.</p>
</ng-template>
Example 2: Conditional formatting inside ngFor
<div *ngFor="let product of products">
<span [ngClass]="{ 'text-red': product.stock === 0 }">
{{ product.name }}
</span>
<span *ngIf="product.stock === 0">
(Out of Stock)
</span>
</div>
Example 3: Skip items using ngIf inside ngFor
<li *ngFor="let user of users">
<span *ngIf="user.isActive">{{ user.name }}</span>
</li>
✔ Only active users will be shown.
6. Common Mistakes to Avoid
| Mistake | Why It's Wrong | Correct |
|---|
Using both ngFor and ngIf in the same tag | Angular does NOT allow two structural directives on one element | Use an extra <ng-container> |
Missing trackBy in large lists | Causes unnecessary re-renders | Always use trackBy for performance |
| Writing complex logic inside templates | Makes HTML messy | Move logic to TypeScript |
7. Using <ng-container> Safely
Angular does not allow:
<li *ngFor="let user of users" *ngIf="user.isActive"> ❌
Use:
<ng-container *ngFor="let user of users">
<li *ngIf="user.isActive">
{{ user.name }}
</li>
</ng-container>
✔ <ng-container> does not create extra DOM elements.
8. Real-World Example (Employee List with Conditions)
Component.ts
employees = [
{ name: 'Raj', role: 'Developer', isActive: true },
{ name: 'Sneha', role: 'Manager', isActive: false },
{ name: 'John', role: 'Tester', isActive: true }
];
Component.html
<h3>Active Employees</h3>
<ul>
<ng-container *ngFor="let emp of employees">
<li *ngIf="emp.isActive">
{{ emp.name }} – {{ emp.role }}
</li>
</ng-container>
</ul>
Conclusion
ngFor and ngIf are powerful Angular tools that help you:
✔ Display lists of dynamic data
✔ Condition the visibility of elements
✔ Build flexible and professional UI layouts
Understanding these two directives is the foundation for mastering Angular templates.