You can add directives to the HTML in your Angular project. Some control the structure of your markup while others focus on attributes.
This article will go through the six most common Angular directives: ngFor, ngIf, ngClass, ngStyle, ngModel, and ngSwitch.
What Are Angular Directives?
Angular directives allow you to use if statements and for loops, and add other behavior to the HTML code of an Angular project.
Directive |
Description |
---|---|
*ngIf |
You can use ngIf when you want certain HTML blocks to only display if they meet a certain condition. For example, if you had a form with a pop-up that displays after a user has entered input for a certain field. |
*ngFor |
You can use ngFor if you need a certain block to repeat many times. For example, if you had a list of items and needed to display a div for each item. |
*ngClass |
This adds conditional styling using a class. If an if-statement meets the condition, it will apply the class specified. |
*ngStyle |
This adds conditional in-line styling. If an if-statement meets the condition, it will apply the styles specified. |
*ngModel |
This allows you to do two-way binding. This means you can pass data in both directions between the HTML and TypeScript file. For instance, you can pass an attribute's value from the TypeScript file to the HTML file, and vice versa. |
*ngSwitch |
This allows you to add a switch statement with many cases to check many values. Based on the cases, certain HTML elements will show. |
Structural directives involve the structure of the HTML elements. These include ngIf, ngFor, and ngSwitch. Attribute directives involve changing the properties of the HTML elements. These include ngStyle, ngClass, and ngModel.
How to Use ngIf
To use ngIf, you will need a condition to evaluate to true for a particular HTML element to show.
-
Add two variables to your TypeScript file. In this example, there is a noPlaylists variable and a variable to store the playlists. This variable will evaluate to true if the length of the playlists array is 0.
noPlaylists: boolean = false;
playlists: any = [];
constructor() { }
ngOnInit(): void {
if(this.playlists.length === 0) {
this.noPlaylists = true;
}
} -
In the HTML, add the *ngIf statement. If noPlaylists is true, the error message contained in the span below will appear. Otherwise, it will not. You can apply ngIf to different types of HTML tags.
<div *ngIf="noPlaylists" class="center">
<span class="errorMessage">There are no playlists available.</span>
</div> -
To add an "else" component to the if-statement, you will need to add the HTML code for the "else" part in a template block.
<div *ngIf="noPlaylists; else playlistsExist" class="center">
<span class="errorMessage">There are no playlists available.</span>
</div>
<ng-template #playlistsExist>
<div class="center">
<span class="successMessage">Playlists found.</span>
</div>
</ng-template>
How to Use ngFor
If you need to repeat a certain number of blocks on a page, you can use the ngFor directive.
-
In the TypeScript file, add items to the array.
playlists: any = [
{"name": "Rock", "numberOfSongs": 5},
{"name": "Contemporary", "numberOfSongs": 9},
{"name": "Popular", "numberOfSongs": 14},
{"name": "Acoustic", "numberOfSongs": 3},
{"name": "Wedding Songs", "numberOfSongs": 25},
{"name": "Metal", "numberOfSongs": 0},
]; -
In the HTML file, add the *ngFor statement.
<span class="successMessage">Playlists found.</span>
<div *ngFor="let playlist of playlists" class="item">
<div class="flex">
<span>{{playlist.name}}</span>
<span>{{playlist.numberOfSongs}} songs</span>
</div>
</div>
How to Use ngClass
You can change the styling class that a particular div uses, based on a condition.
-
Add two classes into the CSS file with different styles. You can add any kind of CSS styling you want, such as different background colors.
.songs {
background-color: #F7F5F2;
}
.noSongs {
background-color: #FFA8A8;
} -
Within the for-loop from the previous step, add the ngClass attribute directive. [ngClass]="playlist.numberOfSongs > 0 ? 'songs' : 'noSongs'" is using the same ternary operator that JavaScript and other languages use.
<div *ngFor="let playlist of playlists" class="item" [ngClass]="playlist.numberOfSongs > 0 ? 'songs' : 'noSongs'">
<div class="flex">
<span>{{playlist.name}}</span>
<span>{{playlist.numberOfSongs}} songs</span>
</div>
</div>
How to Use ngStyle
Instead of using ngClass, you can use ngStyle if you want to apply in-line styling instead of styling via a class.
-
Change the ngClass from the previous step to use ngStyle instead.
<div *ngFor="let playlist of playlists" class="item" [ngStyle]="{'background-color': playlist.numberOfSongs > 0 ? '#F7F5F2' : '#FFA8A8' }>
<div class="flex">
<span>{{playlist.name}}</span>
<span>{{playlist.numberOfSongs}} songs</span>
</div>
</div> -
If you need to apply more than one inline style, you can separate each style with a comma.
[ngStyle]="{'background-color': playlist.numberOfSongs > 0 ? '#F7F5F2' : '#FFA8A8', 'color': playlist.numberOfSongs > 0 ? 'black' : 'darkblue' }"
How to Use ngModel
You can use ngModel for two-way binding. This means you can pass the value of an attribute between both HTML and TypeScript files.
For instance, say you have an input element in the HTML file that uses ngModel. The ngModel attribute is bound to a variable in the TypeScript file. When you enter a value into the input, it will update the variable in the TypeScript file.
The changes made to the attribute in the TypeScript file will also reflect in the HTML if other divs are using that variable.
-
In app.module.ts, add the FormsModule into the imports at the top of the file, and also to the imports array.
import { FormsModule } from '@angular/forms';
@NgModule({
imports: [
...
FormsModule
]
}) -
Add an attribute in the TypeScript file to keep track of when the user is renaming a playlist.
renamingPlaylists: boolean = false;
-
Make the playlists variable public so that this can be accessible when using ngModel in the HTML file.
public playlists: any = [
...
]; -
Add two buttons in the HTML file, which will allow you to rename or cancel renaming each playlist.
<button type="button" class="btn btn-info" *ngIf="!renamingPlaylists" (click)="renamingPlaylists=true">Rename Playlists</button>
<button type="button" class="btn btn-info" *ngIf="renamingPlaylists" (click)="renamingPlaylists=false">Stop renaming</button> -
Add an input box inside each playlist's div. The input will only be visible when you click on the Rename Playlist button. This input box will have an ngModel bound to "playlist.name".
<input type="text" *ngIf="renamingPlaylists" class="form-control input-field" id="name" required [(ngModel)]="playlist.name" />
How to Use ngSwitch
You can use ngSwitch to display certain elements based on the cases within a switch case.
-
Add a new "rating" attribute to the objects inside the playlists array. This attribute can be any number between 0 and 5 (inclusive).
public playlists: any = [
{"name": "Rock", "numberOfSongs": 5, "rating": 5},
{"name": "Contemporary", "numberOfSongs": 9, "rating": 1},
{"name": "Popular", "numberOfSongs": 14, "rating": 5},
{"name": "Acoustic", "numberOfSongs": 3, "rating": 4},
{"name": "Wedding Songs", "numberOfSongs": 25, "rating": 5},
{"name": "Metal", "numberOfSongs": 0, "rating": 0},
]; -
Add a switch case below the name and number of songs for a playlist. Based on the rating number for the playlist, the playlist will show the correct number of stars.
<div class="flex">
<span>{{playlist.name}}</span>
<span>{{playlist.numberOfSongs}} songs</span>
</div>
<div [ngSwitch]="playlist.rating" style="text-align:right">
<div *ngSwitchCase="'1'">★</div>
<div *ngSwitchCase="'2'">★★</div>
<div *ngSwitchCase="'3'">★★★</div>
<div *ngSwitchCase="'4'">★★★★</div>
<div *ngSwitchCase="'5'">★★★★★</div>
<div *ngSwitchDefault>No ratings</div>
</div>
Learning More With Angular
Now you have learned the basics of Angular directives, including how to use ngIf, ngFor, ngClass, ngStyle, ngModel, and ngSwitch. You can combine them to create more complex user interfaces. There is so much more for you to explore and learn about Angular, no matter whether you are a beginner or at an advanced level.