Structural Directives in Angular
Swipe to show menu
When building user interfaces for web applications, we often face scenarios like "Display a list of items if it's available, or show a placeholder if it's empty." In Angular, these kinds of tasks are handled using structural directives โ powerful tools that control what gets rendered in the template and when.
Unlike regular HTML attributes, structural directives don't just tweak an element's behavior โ they actually change the structure of the DOM by adding or removing entire elements.
Structural Directive NgFor
Let's say you have a list of tasks in our TaskListComponent. Each task should be shown with its own interface elements: a delete button, a status toggle, etc. Writing each task manually in the HTML would be inefficient and difficult to maintain as the data changes.
tasks = [
{ id: 1, title: 'Buy groceries', completed: false },
{ id: 2, title: 'Walk the dog', completed: true },
{ id: 3, title: 'Learn Angular', completed: false }
];
Angular provides the *ngFor directive, which lets you loop through an array and automatically generate an HTML element for each item.
<task-component *ngFor="let task of tasks"></task-component>
Here, *ngFor="let task of tasks" tells Angular: "For every task in the tasks array, create one <task-component>".
If the array contains 3 tasks, Angular will render 3 separate task-component instances, each with its own data. This makes the UI more scalable and eliminates repetitive code.
Extra Features of ngFor
In addition to basic iteration, *ngFor supports several useful context variables you can access directly in the directive using let.
Here's a quick reference:
Here's an example using some of them:
<task-component
*ngFor="let task of tasks; let i = index; let odd = odd"
[task]="task"
[class.odd]="odd">
</task-component>
In this example, the odd variable is used to apply a CSS class to every other row, making the list visually easier to scan.
Structural Directive NgIf
Let's take a look at how conditional rendering works using a simple task list example. You want to display the list if it contains tasks, and if it's empty, show a message like "No tasks yet".
In Angular, you use the *ngIf directive to conditionally show or hide elements. While it looks like a regular HTML attribute, it actually does much more behind the scenes.
<div *ngIf="tasks.length > 0">Task List</div>
When Angular processes *ngIf, it rewrites the template behind the scenes. Instead of rendering the element directly, it wraps it inside an <ng-template>, and only adds it to the DOM if the condition is true.
<ng-template [ngIf]="tasks.length > 0">
<div>Task List</div>
</ng-template>
If the condition evaluates to false (i.e., tasks.length === 0), Angular doesn't render the element at all โ it's completely absent from the DOM.
But what if you want to show a fallback message instead of simply hiding the content? That's where the else clause of *ngIf comes in handy. It allows you to reference an alternative template using an <ng-template> with a custom label.
task-list.ts
task-list.css
Here's what happens:
-
Angular first checks if the
tasksarray has any items; -
If it does, it renders the
<div>with the task components; -
If the array is empty, it uses the
#noTaskstemplate and displays the message: "No tasks yet ๐".
This makes your templates much cleaner and helps manage empty states in a user-friendly way.
1. What does the *ngIf directive do?
2. What is the purpose of *ngFor in Angular?
3. What happens if *ngIf="false"?
Thanks for your feedback!
Ask AI
Ask AI
Ask anything or try one of the suggested questions to begin our chat