LearnAI ToolsCareerPractice BuildsPlayContact
Lesson 1218 min read

Structural Directives (*ngIf, *ngFor)

Control what renders and how many times using the classic structural directives and the modern @if/@for control-flow syntax.

What Is a Structural Directive?

A structural directive changes the actual structure of the DOM — adding, removing, or repeating elements — rather than just setting a property. Classic structural directives are prefixed with an asterisk in templates, a shorthand for a more verbose underlying syntax.

*ngIf

*ngIf adds or removes an element from the DOM entirely, based on whether its expression is truthy.

<p *ngIf="isLoggedIn">Welcome back!</p>
<p *ngIf="!isLoggedIn">Please log in.</p>

For an else branch, use ng-template with a template reference.

<p *ngIf="isLoggedIn; else loggedOut">Welcome back!</p>
<ng-template #loggedOut>
<p>Please log in.</p>
</ng-template>

*ngFor

*ngFor repeats an element once per item in an array, following a "let item of items" syntax.

<ul>
<li *ngFor="let fruit of fruits; let i = index">
{{ i }}: {{ fruit }}
</li>
</ul>
Track Items for Performance

For large or frequently-changing lists, add trackBy (classic *ngFor) or rely on @for's required track expression (modern syntax) so Angular can correctly identify and reuse DOM nodes across updates instead of recreating everything.

The Modern @if / @for Syntax

Modern Angular (17+) introduces a new, built-in control-flow syntax — @if, @for, @switch — that replaces *ngIf/*ngFor with cleaner syntax and better performance, without needing CommonModule imported at all.

@if (isLoggedIn) {
<p>Welcome back!</p>
} @else {
<p>Please log in.</p>
}
<ul>
@for (fruit of fruits; track fruit) {
<li>{{ fruit }}</li>
} @empty {
<li>No fruits available.</li>
}
</ul>
ClassicModern
*ngIf="cond"@if (cond) { ... }
*ngIf="cond; else tpl"@if (cond) { ... } @else { ... }
*ngFor="let x of items"@for (x of items; track x) { ... }
Requires CommonModule importBuilt into the template compiler, no import needed

Common Beginner Mistakes

Forgetting to import CommonModule for *ngIf/*ngFor

Classic structural directives require CommonModule in a standalone component's imports array — the modern @if/@for syntax avoids this entirely.

Omitting track in the modern @for syntax

Unlike *ngFor's optional trackBy, @for requires a track expression — Angular won't compile without one.

FAQs

Use the modern @if/@for/@switch syntax for new projects — it's simpler, doesn't need CommonModule, and performs better. This course uses classic syntax in early examples for broad familiarity, then shows the modern equivalent.

Very close — both conditionally render content, though @if compiles more efficiently and its @else if chains are more readable than nested *ngIf/ng-template combinations.

Summary

Structural directives control whether and how many times something renders, with modern Angular's @if/@for offering a cleaner, import-free alternative to the classic asterisk syntax. Next, you'll learn attribute directives, which modify an existing element rather than adding/removing it.

Next Lesson →

Attribute Directives