Tutorials Logic, IN +91 8092939553 info@tutorialslogic.com
FAQs Support
Navigation
Home About Us Contact Us Blogs FAQs
Tutorials
All Tutorials
Services
Academic Projects Resume Writing Interview Questions Website Development
Compiler Tutorials

Template Syntax in Angular

Interpolation

Use double curly braces {{ }} to embed expressions in the template. Angular evaluates the expression and converts the result to a string.

Interpolation
import { Component, signal } from '@angular/core';

@Component({ selector: 'app-demo', standalone: true, templateUrl: './demo.component.html' })
export class DemoComponent {
    name    = signal('Angular');
    version = signal(21);
    price   = signal(9.99);
    items   = signal(['Apple', 'Banana', 'Cherry']);
}
<!-- Basic interpolation -->
<h1>Hello, {{ name() }}!</h1>
<p>Version: {{ version() }}</p>

<!-- Expressions -->
<p>Price: ${{ price() | number:'1.2-2' }}</p>
<p>Items: {{ items().length }}</p>
<p>Upper: {{ name().toUpperCase() }}</p>
<p>Sum: {{ 1 + 2 + 3 }}</p>

Property Binding

Bind a DOM property to a component expression using square brackets [property]="expression".

Property Binding
<!-- Bind to DOM properties -->
<img [src]="imageUrl()" [alt]="imageAlt()" />
<button [disabled]="isLoading()">Submit</button>
<input [value]="username()" />

<!-- Class and style binding -->
<div [class.active]="isActive()">...</div>
<div [class]="{ active: isActive(), error: hasError() }">...</div>
<p [style.color]="textColor()">Styled text</p>
<p [style]="{ fontSize: fontSize() + 'px', fontWeight: 'bold' }">...</p>

<!-- Attribute binding (for non-DOM attributes like aria-*) -->
<button [attr.aria-label]="buttonLabel()">Click</button>

Event Binding

Listen to DOM events using parentheses (event)="handler($event)".

Event Binding
export class EventDemoComponent {
    count = signal(0);
    inputValue = signal('');

    increment() { this.count.update(v => v + 1); }
    onInput(event: Event) {
        this.inputValue.set((event.target as HTMLInputElement).value);
    }
    onKeydown(event: KeyboardEvent) {
        if (event.key === 'Enter') console.log('Enter pressed');
    }
}
<button (click)="increment()">Count: {{ count() }}</button>
<input (input)="onInput($event)" (keydown)="onKeydown($event)" />
<p>You typed: {{ inputValue() }}</p>

<!-- Inline expression -->
<button (click)="count.set(0)">Reset</button>

Two-Way Binding

Two-Way Binding
import { Component, signal } from '@angular/core';
import { FormsModule } from '@angular/forms';

@Component({
    selector: 'app-two-way',
    standalone: true,
    imports: [FormsModule],
    templateUrl: './two-way.component.html'
})
export class TwoWayComponent {
    username = signal('');
}
<!-- [(ngModel)] requires FormsModule -->
<input [(ngModel)]="username" placeholder="Enter name" />
<p>Hello, {{ username() }}!</p>

<!-- Equivalent manual two-way -->
<input [value]="username()" (input)="username.set($any($event.target).value)" />

Built-in Control Flow (Angular 17+)

Angular 17 introduced a new built-in control flow syntax using @if, @for, and @switch — replacing *ngIf, *ngFor, and *ngSwitch. This is the recommended approach in Angular 21.

@if, @for, @switch
<!-- @if / @else if / @else -->
@if (isLoggedIn()) {
    <p>Welcome back, {{ username() }}!</p>
} @else if (isGuest()) {
    <p>Browsing as guest</p>
} @else {
    <a href="/login">Please log in</a>
}
<!-- @for with track (required) -->
@for (item of items(); track item.id) {
    <li>{{ item.name }} — ${{ item.price }}</li>
} @empty {
    <li>No items found</li>
}

<!-- Loop variables -->
@for (item of items(); track item.id; let i = $index, last = $last) {
    <li [class.last]="last">{{ i + 1 }}. {{ item.name }}</li>
}
<!-- @switch -->
@switch (status()) {
    @case ('loading') {
        <app-spinner />
    }
    @case ('error') {
        <app-error-message />
    }
    @case ('success') {
        <app-data-table />
    }
    @default {
        <p>Unknown status</p>
    }
}

Template Reference Variables

Template Variables
<!-- #ref creates a reference to the element -->
<input #nameInput type="text" />
<button (click)="greet(nameInput.value)">Greet</button>

<!-- Reference to a component -->
<app-child #child />
<button (click)="child.doSomething()">Call child method</button>

<!-- @defer — lazy load a block -->
@defer (on viewport) {
    <app-heavy-component />
} @placeholder {
    <p>Scroll down to load...</p>
} @loading {
    <app-spinner />
}

Ready to Level Up Your Skills?

Explore 500+ free tutorials across 20+ languages and frameworks.