Angular Template Syntax
Introduction
Angular Template Syntax is the special language used within Angular HTML templates to create dynamic, interactive web applications. It extends standard HTML with Angular-specific syntax features that allow you to bind data, respond to events, render content conditionally, and much more—all directly from your templates.
Understanding template syntax is crucial for Angular development as it forms the bridge between your application's component logic and what users see on screen. In this guide, we'll explore the core elements of Angular's template syntax and how to use them effectively.
Template Expressions and Statements
Interpolation
Interpolation is the simplest form of data binding in Angular, allowing you to embed expressions directly into your HTML. Angular will evaluate these expressions and convert them to string output.
Syntax: {{ expression }}
<h1>{{ title }}</h1>
<p>{{ 'Hello, ' + username }}</p>
<div>Sum: {{ 1 + 1 }}</div>
Output (assuming title = 'Welcome to Angular'
and username = 'John'
):
Welcome to Angular
Hello, John
Sum: 2
Interpolation expressions:
- Can access component properties
- Can call component methods
- Can include simple arithmetic operations
- Cannot contain assignments (=)
- Cannot use global JavaScript references like
window
ordocument
- Should be fast and have no side effects
Property Binding
Property binding allows you to set HTML element properties, directive properties, or component inputs using values from your component.
Syntax: [property]="expression"
<img [src]="userProfileImage">
<button [disabled]="isSubmitting">Submit</button>
<app-profile [userId]="currentUser.id"></app-profile>
Property binding is one-way, from component to DOM. When your component data changes, the bound property is updated automatically.
Attribute, Class, and Style Binding
While property binding works with DOM properties, sometimes you need to bind to HTML attributes, classes, or styles:
Attribute binding:
<button [attr.aria-label]="actionDescription">Action</button>
Class binding:
<!-- Single class binding -->
<div [class.active]="isActive">This div is active</div>
<!-- Multiple class binding -->
<div [ngClass]="{'active': isActive, 'disabled': isDisabled}">Dynamic classes</div>
Style binding:
<!-- Single style binding -->
<div [style.color]="isError ? 'red' : 'black'">Message text</div>
<!-- Multiple style binding -->
<div [ngStyle]="{'color': textColor, 'font-size': fontSize + 'px'}">Styled text</div>
Event Binding
Event binding allows you to listen for and respond to user actions like clicks, keypresses, mouse movements, and more.
Syntax: (event)="statement"
<button (click)="saveData()">Save</button>
<input (keyup)="onKeyUp($event)" placeholder="Type something">
<div (mouseover)="showTooltip()" (mouseout)="hideTooltip()">Hover me</div>
The $event
object represents the DOM event and can be passed to your component methods:
<input (keyup)="updateValue($event)">
updateValue(event: any) {
this.inputValue = event.target.value;
}
Two-Way Binding
Two-way binding combines property binding and event binding, providing a convenient way to update data in both directions (from component to view and from view to component).
Syntax: [(ngModel)]="property"
<input [(ngModel)]="username">
<p>You typed: {{ username }}</p>
To use ngModel
, make sure to import FormsModule
in your module:
import { FormsModule } from '@angular/forms';
@NgModule({
imports: [
FormsModule
]
})
Under the hood, two-way binding is actually syntactic sugar for a property binding and an event binding:
<!-- This: -->
<input [(ngModel)]="username">
<!-- Is equivalent to: -->
<input [ngModel]="username" (ngModelChange)="username = $event">
Template Reference Variables
Template reference variables let you reference elements in your template, making it easier to interact with DOM elements.
Syntax: #variableName
<input #nameInput type="text">
<button (click)="greet(nameInput.value)">Greet</button>
greet(name: string) {
alert(`Hello, ${name}!`);
}
Built-in Directives
Angular provides several built-in directives that help you manipulate the DOM structure.
Structural Directives
Structural directives change the DOM layout by adding, removing, or manipulating elements. They are prefixed with an asterisk (*
).
*ngIf
Conditionally includes an element based on an expression:
<div *ngIf="isLoggedIn">Welcome back, {{ username }}!</div>
<div *ngIf="!isLoggedIn">Please log in to continue.</div>
<!-- With else clause -->
<div *ngIf="isLoggedIn; else loginBlock">Welcome, {{ username }}!</div>
<ng-template #loginBlock>
<div>Please log in to continue.</div>
</ng-template>
*ngFor
Repeats a template for each item in an array:
<ul>
<li *ngFor="let item of items; let i = index">
{{ i + 1 }}. {{ item.name }}
</li>
</ul>
Additional variables available in *ngFor
:
index
: The position of the current item (0-based)first
: Boolean, true if the current item is the first itemlast
: Boolean, true if the current item is the last itemeven
: Boolean, true if the current index is evenodd
: Boolean, true if the current index is odd
*ngSwitch
Selects one element to display from multiple options:
<div [ngSwitch]="userRole">
<div *ngSwitchCase="'admin'">Admin Panel</div>
<div *ngSwitchCase="'editor'">Editor Tools</div>
<div *ngSwitchDefault>User Dashboard</div>
</div>
Attribute Directives
Attribute directives change the appearance or behavior of an element.
ngClass
Adds or removes CSS classes:
<div [ngClass]="{'active': isActive, 'disabled': isDisabled, 'highlight': isHighlighted}">
Dynamic styling
</div>
ngStyle
Adds or removes inline styles:
<div [ngStyle]="{'color': textColor, 'background-color': bgColor, 'font-size.px': fontSize}">
Dynamically styled text
</div>
Pipes
Pipes transform displayed values within a template. Angular provides several built-in pipes.
Syntax: {{ value | pipeName:parameter1:parameter2 }}
<p>{{ currentDate | date:'short' }}</p>
<p>{{ price | currency:'USD' }}</p>
<p>{{ message | uppercase }}</p>
<p>{{ longText | slice:0:100 }}...</p>
You can chain pipes:
<p>{{ currentDate | date:'fullDate' | uppercase }}</p>
Practical Example: User Profile Component
Let's consolidate our knowledge with a practical example of a user profile component:
// user-profile.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-user-profile',
templateUrl: './user-profile.component.html',
styleUrls: ['./user-profile.component.css']
})
export class UserProfileComponent {
user = {
name: 'John Doe',
email: '[email protected]',
role: 'developer',
active: true,
skills: ['HTML', 'CSS', 'JavaScript', 'Angular'],
joinDate: new Date(2020, 1, 15)
};
editMode = false;
toggleEditMode() {
this.editMode = !this.editMode;
}
updateSkill(skillInput: HTMLInputElement) {
if (skillInput.value && !this.user.skills.includes(skillInput.value)) {
this.user.skills.push(skillInput.value);
skillInput.value = '';
}
}
removeSkill(skill: string) {
this.user.skills = this.user.skills.filter(s => s !== skill);
}
}
<!-- user-profile.component.html -->
<div class="card" [ngClass]="{'inactive': !user.active}">
<h2>User Profile</h2>
<div *ngIf="!editMode; else editTemplate">
<p><strong>Name:</strong> {{ user.name }}</p>
<p><strong>Email:</strong> {{ user.email }}</p>
<p><strong>Role:</strong> {{ user.role | titlecase }}</p>
<p><strong>Status:</strong>
<span [style.color]="user.active ? 'green' : 'red'">
{{ user.active ? 'Active' : 'Inactive' }}
</span>
</p>
<p><strong>Member since:</strong> {{ user.joinDate | date:'mediumDate' }}</p>
<div>
<strong>Skills:</strong>
<ul>
<li *ngFor="let skill of user.skills; let i = index">
{{ i + 1 }}. {{ skill }}
</li>
</ul>
</div>
<button (click)="toggleEditMode()">Edit Profile</button>
</div>
<ng-template #editTemplate>
<div>
<div class="form-group">
<label for="name">Name:</label>
<input id="name" [(ngModel)]="user.name">
</div>
<div class="form-group">
<label for="email">Email:</label>
<input id="email" [(ngModel)]="user.email">
</div>
<div class="form-group">
<label for="role">Role:</label>
<select id="role" [(ngModel)]="user.role">
<option value="developer">Developer</option>
<option value="designer">Designer</option>
<option value="manager">Manager</option>
</select>
</div>
<div class="form-group">
<label>Status:</label>
<input type="checkbox" [(ngModel)]="user.active"> Active
</div>
<div class="form-group">
<label>Skills:</label>
<ul>
<li *ngFor="let skill of user.skills">
{{ skill }}
<button (click)="removeSkill(skill)">Remove</button>
</li>
</ul>
<div>
<input #newSkill placeholder="New skill">
<button (click)="updateSkill(newSkill)">Add Skill</button>
</div>
</div>
<button (click)="toggleEditMode()">Save Profile</button>
</div>
</ng-template>
</div>
This example demonstrates:
- Interpolation to display user data
- Property binding for dynamic classes and styles
- Event binding for button clicks
- Two-way binding with form inputs
- Structural directives for conditional rendering and lists
- Template reference variables for accessing input values
- Pipes for formatting dates and text
Summary
Angular template syntax is a powerful feature that enables you to create dynamic and interactive web applications. In this guide, we've covered:
- Interpolation for displaying component data
- Property binding for setting element properties
- Event binding for handling user interactions
- Two-way binding for form inputs
- Template reference variables for accessing DOM elements
- Structural directives like
*ngIf
and*ngFor
for DOM manipulation - Attribute directives like
ngClass
andngStyle
for dynamic styling - Pipes for data transformation
Understanding these concepts is essential for effective Angular development, as they form the foundation for building interactive UIs that respond to user actions and display dynamic data.
Further Learning Resources
- Official Angular Template Syntax Guide
- Angular Template Reference Variables
- Angular Pipes Documentation
Exercises
- Create a to-do list component that demonstrates
*ngFor
and event handling - Build a simple calculator with two-way binding for inputs
- Create a data table with sorting functionality using template variables and event binding
- Implement a form with validation that uses conditional styling with
ngClass
- Build a component that demonstrates all built-in Angular pipes
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)