Angular Templates

Read one Angular interview question at a time, then flip for the complete explanation, example, and code.

0/100 Known filtered set
Level
Read Full Guide Question: 1 of 100

Angular Interview Questions · Angular Templates Companion Article

Angular Templates

Angular templates define what users see in the browser and how that user interface communicates with component data. A template looks similar to HTML, but Angular extends normal HTML with features such as interpolation, property binding, event binding, template variables, expressions, and two-way binding. Instead of building a completely static page, Angular templates allow the displayed content to react to application data and user actions.

Angular Templates Overview

For example, a component may contain:

TypeScript
export class UserComponent {
  userName = 'Rahul';
  isActive = true;
}

The template can display and use this data:

HTML
<h2>{{ userName }}</h2>
<p [class.active]="isActive">User Status</p>

Here, the HTML is connected directly to the component class.

Template Syntax

Angular template syntax is the set of rules Angular provides for connecting HTML with component data and application logic.

A normal HTML page displays fixed content:

HTML
<h1>Welcome</h1>

An Angular template can display dynamic content:

HTML
<h1>Welcome {{ userName }}</h1>

Angular template syntax commonly includes:

  • {{ }} for text interpolation
  • [property] for property binding
  • [attr.attribute] for attribute binding
  • [class.className] for class binding
  • [style.property] for style binding
  • (event) for event binding
  • [(ngModel)] for common form-based two-way binding
  • #variableName for template reference variables

A template should mainly describe the user interface. Complex business logic should normally remain inside the component or another TypeScript class rather than being placed directly in HTML.

Example

TypeScript
export class ProductComponent {
  productName = 'Laptop';
  price = 55000;
  available = true;

  buyProduct() {
    console.log('Product purchased');
  }
}
HTML
<h2>{{ productName }}</h2>
<p>Price: ₹{{ price }}</p>
<button [disabled]="!available" (click)="buyProduct()">
  Buy Now
</button>

This example combines interpolation, property binding, template expressions, and event binding.

Text Interpolation

Text interpolation displays component values inside the template.

Syntax

HTML
{{ expression }}

Example

TypeScript
export class ProfileComponent {
  name = 'Amit';
  role = 'Angular Developer';
}
HTML
<h2>{{ name }}</h2>
<p>{{ role }}</p>

Angular evaluates the expressions and displays their values.

The rendered result would be similar to:

Text
Amit
Angular Developer

Expressions Inside Interpolation

Interpolation is not limited to simple variables.

HTML
<p>{{ firstName + ' ' + lastName }}</p>
<p>{{ price * quantity }}</p>
<p>{{ isLoggedIn ? 'Welcome' : 'Please Login' }}</p>

Method calls can also be used:

HTML
<p>{{ getFullName() }}</p>

However, methods called from templates may be evaluated frequently during rendering and change detection. Expensive calculations are better handled outside the template.

Common Uses

Interpolation is suitable for:

  • Headings
  • Labels
  • Product names
  • User names
  • Calculated values
  • Messages
  • Table data
  • Dynamic text

Property Binding

Property binding passes data from the component to a property of an HTML element, directive, or Angular component.

Syntax

HTML
[property]="expression"

Example

TypeScript
export class ImageComponent {
  imageUrl = 'assets/angular-logo.png';
}
HTML
<img [src]="imageUrl">

The value of imageUrl is assigned to the DOM element's src property.

Another example:

TypeScript
export class FormComponent {
  formDisabled = true;
}
HTML
<button [disabled]="formDisabled">Submit</button>

If formDisabled is true, the button becomes disabled.

Property Binding vs Static Value

Static HTML:

HTML
<img src="assets/logo.png">

Dynamic Angular property binding:

HTML
<img [src]="logoUrl">

Use property binding when the value must come from component data or an Angular expression.

Common Property Bindings

HTML
<input [value]="userName">

<img [src]="profileImage">

<button [disabled]="isDisabled">
  Save
</button>

<a [href]="websiteUrl">
  Visit Website
</a>

Property binding represents one-way communication:

Text
Component Data
      ↓
   Template

Attribute Binding

Property binding and attribute binding are related but are not identical.

Property binding normally updates a DOM property. Attribute binding explicitly updates an HTML attribute.

Syntax

HTML
[attr.attributeName]="expression"

Example

TypeScript
export class TableComponent {
  columnCount = 3;
}
HTML
<td [attr.colspan]="columnCount">
  Product Information
</td>

Attribute binding is especially useful for attributes that do not have a convenient corresponding DOM property.

Accessibility Example

TypeScript
export class ButtonComponent {
  buttonDescription = 'Close dialog';
}
HTML
<button [attr.aria-label]="buttonDescription">
  X
</button>

ARIA attributes are common examples of situations where attribute binding is useful.

Removing an Attribute

When an attribute-binding expression evaluates to null, Angular can remove that attribute.

HTML
<button [attr.title]="showHelp ? 'Click to continue' : null">
  Continue
</button>

Class Binding

Class binding dynamically adds or removes CSS classes based on component data.

Binding a Single Class

HTML
<div [class.active]="isActive">
  Account
</div>

If isActive is true, Angular applies the active class.

Component

TypeScript
export class AccountComponent {
  isActive = true;
}

CSS

CSS
.active {
  font-weight: bold;
}

Binding a Class Value

Angular can also bind the complete class value.

TypeScript
export class AlertComponent {
  currentClass = 'success-message';
}
HTML
<div [class]="currentClass">
  Operation completed
</div>

Practical Example

HTML
<span [class.available]="stock > 0">
  {{ stock > 0 ? 'In Stock' : 'Out of Stock' }}
</span>

Class binding is useful for:

  • Active menu items
  • Validation states
  • Success messages
  • Error messages
  • Selected items
  • Availability indicators
  • Conditional highlighting

Style Binding

Style binding changes an element's inline CSS style dynamically.

Syntax

HTML
[style.property]="expression"

Example

TypeScript
export class ProgressComponent {
  textColor = 'green';
}
HTML
<p [style.color]="textColor">
  Completed
</p>

Binding Numeric Values with Units

Angular allows units to be included in style bindings.

TypeScript
export class BoxComponent {
  boxWidth = 250;
}
HTML
<div [style.width.px]="boxWidth">
  Content
</div>

Other units can also be used where appropriate:

HTML
<div [style.width.%]="progress"></div>

Conditional Styling

HTML
<p [style.color]="isError ? 'red' : 'green'">
  {{ message }}
</p>

Style binding is useful when a style value genuinely depends on application state. For larger styling changes involving reusable visual states, class binding is often easier to maintain.

Event Binding

Event binding sends information from the template to the component when a user or browser event occurs.

Syntax

HTML
(event)="statement"

Click Example

TypeScript
export class CounterComponent {
  count = 0;

  increment() {
    this.count++;
  }
}
HTML
<button (click)="increment()">Increase</button>

<p>Count: {{ count }}</p>

When the user clicks the button, Angular calls increment().

The data flow is:

Text
User Action
    ↓
Template Event
    ↓
Component Method

Common Events

HTML
<button (click)="save()">Save</button>

<input (input)="onInput($event)">

<input (keyup)="onKeyUp($event)">

<input (focus)="onFocus()">

<input (blur)="onBlur()">

<form (submit)="submitForm()">

Using $event

Angular provides the special $event variable for accessing information about the current event.

HTML
<input (input)="onInput($event)">

Component:

TypeScript
onInput(event: Event) {
  const input = event.target as HTMLInputElement;
  console.log(input.value);
}

$event contains the event object generated by the browser or component.

Keyboard Event Filtering

Templates can react to particular keyboard events.

HTML
<input (keyup.enter)="search()">

The search() method runs when Enter is pressed.

Two-Way Binding

Two-way binding allows data to move in both directions between the component and the template.

Conceptually:

Text
Component
    ↓
Template

Component
    ↑
Template

A common example is a form input whose value should stay synchronized with a component property.

ngModel Example

TypeScript
export class UserComponent {
  userName = '';
}
HTML
<input [(ngModel)]="userName">

<p>Hello {{ userName }}</p>

When the user enters text, userName changes. When userName changes programmatically, the input can also reflect the new value.

The syntax:

HTML
[(ngModel)]="userName"

combines property-style and event-style communication.

The [()] syntax is sometimes informally called banana-in-a-box syntax because of the shape of the brackets and parentheses.

Forms Requirement

When using ngModel, the appropriate Angular forms support must be imported into the application or component.

For standalone components, this commonly means importing FormsModule.

TypeScript
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';

@Component({
  selector: 'app-user',
  standalone: true,
  imports: [FormsModule],
  templateUrl: './user.component.html'
})
export class UserComponent {
  userName = '';
}

When Two-Way Binding Is Useful

It is commonly used for:

  • Search fields
  • Simple forms
  • Settings
  • Filters
  • Editable values
  • User input controls

For complex enterprise forms, Angular's reactive forms approach may provide clearer control over validation and form state.

Template Expressions

A template expression is code Angular evaluates to produce a value.

Examples:

HTML
{{ userName }}

{{ price * quantity }}

{{ firstName + ' ' + lastName }}

{{ isLoggedIn ? 'Logout' : 'Login' }}

<img [src]="imageUrl">

The following are examples of expressions:

Text
userName
price * quantity
firstName + ' ' + lastName
isLoggedIn ? 'Logout' : 'Login'
imageUrl

Keep Expressions Simple

This is easy to understand:

HTML
<p>{{ totalPrice }}</p>

A long calculation directly inside a template is harder to maintain:

HTML
<p>{{ price * quantity - price * quantity * discount / 100 + deliveryCharge }}</p>

It may be clearer to calculate the result in TypeScript and expose a meaningful property or method.

Good Template Expression Characteristics

Template expressions should generally be:

  • Short
  • Easy to read
  • Fast to evaluate
  • Free from complicated business logic
  • Focused on displaying UI state

Template Statements

Template statements respond to events.

Example:

HTML
<button (click)="saveUser()">Save</button>

Here:

Text
saveUser()

is executed because of the click event.

A statement may also update a property:

HTML
<button (click)="count = count + 1">
  Increase
</button>

Another example:

HTML
<button (click)="selectedProduct = product">
  Select
</button>

Expression vs Statement

Consider:

HTML
<p>{{ userName }}</p>

userName is evaluated to produce a value. It is a template expression.

Now consider:

HTML
<button (click)="saveUser()">Save</button>

saveUser() is executed in response to an event. In this context, it is a template statement.

A useful distinction is:

Template ExpressionTemplate Statement
Produces a valuePerforms an action
Common in interpolationCommon in event binding
Common in property bindingRuns after an event
Example: price * quantityExample: save()

Template Variables

Angular templates can introduce variables that are available within a particular template context.

A common example appears when iterating over data.

With modern Angular control flow:

HTML
@for (product of products; track product.id; let i = $index) {
  <p>{{ i + 1 }}. {{ product.name }}</p>
}

Here:

Text
product
i

are variables available within the relevant template block.

The variable product represents the current item, while i receives the current index.

Template variables are useful when working with:

  • Repeated items
  • Conditional blocks
  • Local template context
  • Template fragments
  • Forms
  • Child elements and components

Their scope normally belongs to the template region in which Angular creates them.

Safe Navigation

Applications frequently work with data that may not be immediately available.

Consider:

TypeScript
user?: {
  name: string;
};

Trying to access nested data without checking it can cause problems when an object is missing.

Angular templates support optional chaining, commonly known historically in Angular documentation and discussions as the safe navigation operator.

Syntax

HTML
{{ user?.name }}

If user exists, Angular reads name.

If user is null or undefined, Angular avoids attempting normal property access on the missing value.

Nested Example

HTML
<p>{{ user?.address?.city }}</p>

Angular safely evaluates each level.

This is particularly useful when data arrives asynchronously:

TypeScript
user?: User;

ngOnInit() {
  this.loadUser();
}

The template may render before the user information has been loaded.

Instead of:

HTML
<p>{{ user.name }}</p>

a guarded access can be used:

HTML
<p>{{ user?.name }}</p>

Default Value with Nullish Coalescing

Optional chaining can be combined with a fallback:

HTML
<p>{{ user?.name ?? 'Guest' }}</p>

If the name is unavailable, the template displays Guest.

Template Reference Variables

A template reference variable provides a reference to an element, component, directive, or other template object.

Syntax

HTML
#variableName

Basic Example

HTML
<input #nameInput>

<button (click)="showName(nameInput.value)">
  Show Name
</button>

Here:

Text
#nameInput

creates a reference to the input element.

The button can then access:

Text
nameInput.value

Component Method

TypeScript
showName(name: string) {
  console.log(name);
}

Another Example

HTML
<input #searchBox type="text">

<button (click)="search(searchBox.value)">
  Search
</button>

Template reference variables are useful when a template needs direct access to a local element or Angular object without creating a component property for every small interaction.

Scope

A template reference variable should only be used where it is available in the template's scope. It should not be treated as a global application variable.

Understanding Angular Data Flow

Most Angular template features become easier to understand when they are grouped by the direction in which information moves.

Component to Template

These features mainly move or expose data from TypeScript to the UI:

Text
Interpolation
Property Binding
Attribute Binding
Class Binding
Style Binding

Example:

HTML
<h2>{{ productName }}</h2>
<img [src]="productImage">
<button [disabled]="soldOut">Buy</button>

Template to Component

Event binding moves information generated by user interaction toward the component.

HTML
<button (click)="addToCart()">Add to Cart</button>

Flow:

Text
User clicks button
        ↓
Angular detects click
        ↓
addToCart() executes
        ↓
Component state can change

Both Directions

Two-way binding synchronizes values in both directions.

HTML
<input [(ngModel)]="searchText">

Flow:

Text
Component → Input

Component ← Input

Interpolation vs Property Binding

Interpolation and property binding can sometimes appear to accomplish similar tasks.

For example:

HTML
<img src="{{ imageUrl }}">

and:

HTML
<img [src]="imageUrl">

Both can provide a dynamic image URL.

Property binding is generally clearer when working specifically with element properties:

HTML
<img [src]="imageUrl">

Interpolation is naturally suited to text:

HTML
<p>Welcome {{ userName }}</p>

A useful rule is:

Text
Dynamic text → interpolation
Dynamic element property → property binding

Property Binding vs Attribute Binding

These two concepts are easy to confuse.

Consider:

HTML
<input value="Angular">

HTML initially creates an attribute named value. The browser also exposes a corresponding DOM property.

Angular property binding:

HTML
<input [value]="courseName">

updates the element property.

Attribute binding:

HTML
<td [attr.colspan]="columnCount">

explicitly works with the HTML attribute.

Use normal property binding when the target is available as a DOM or Angular property. Use attr. when an actual attribute needs to be controlled.

Class Binding vs Style Binding

Both can dynamically change an element's appearance.

Class binding:

HTML
<p [class.error]="hasError">
  Invalid value
</p>

Style binding:

HTML
<p [style.color]="hasError ? 'red' : 'green'">
  Status
</p>

Class binding is usually better when several CSS rules represent one visual state.

For example:

CSS
.error {
  color: red;
  font-weight: bold;
  border-left: 3px solid;
}
HTML
<p [class.error]="hasError">
  Invalid value
</p>

Style binding is convenient when only a particular style value needs to change dynamically.

Event Binding vs Property Binding

Property binding and event binding work in opposite directions.

Property Binding

HTML
<button [disabled]="isDisabled">Save</button>
Text
Component → Template

Event Binding

HTML
<button (click)="save()">Save</button>
Text
Template → Component

Remember:

Text
[property] = component sends data

(event) = template sends an event

Practical Example: Product Card

The following small example combines several Angular template concepts.

Component

TypeScript
export class ProductComponent {
  productName = 'Wireless Keyboard';
  productImage = 'assets/keyboard.jpg';
  price = 1499;
  stock = 5;
  quantity = 1;
  selected = false;

  addToCart() {
    console.log('Product added to cart');
  }
}

Template

HTML
<div [class.selected]="selected">

  <img
    [src]="productImage"
    [attr.alt]="productName">

  <h2>{{ productName }}</h2>

  <p>Price: ₹{{ price }}</p>

  <p
    [style.fontWeight]="stock > 0 ? 'bold' : 'normal'">
    {{ stock > 0 ? 'In Stock' : 'Out of Stock' }}
  </p>

  <input
    type="number"
    [(ngModel)]="quantity">

  <button
    [disabled]="stock === 0"
    (click)="addToCart()">
    Add to Cart
  </button>

</div>

This single template demonstrates:

  • Interpolation
  • Property binding
  • Attribute binding
  • Class binding
  • Style binding
  • Event binding
  • Two-way binding
  • Template expressions
  • Template statements

This is closer to how template features are used in real Angular applications: several binding mechanisms work together to represent and update UI state.

Practical Example: Reading Input Without Two-Way Binding

Not every input requires ngModel.

For a simple action, a template reference variable may be enough.

HTML
<input #emailInput type="email">

<button (click)="subscribe(emailInput.value)">
  Subscribe
</button>

Component:

TypeScript
subscribe(email: string) {
  console.log(email);
}

In this situation, creating a component property solely to hold the current input value may not be necessary.

Common Angular Template Mistakes

Forgetting Square Brackets

Incorrect:

HTML
<img src="imageUrl">

This uses the literal text imageUrl.

Correct:

HTML
<img [src]="imageUrl">

Angular now evaluates the component property.

Forgetting Parentheses for Events

Incorrect:

HTML
<button click="save()">Save</button>

Correct:

HTML
<button (click)="save()">Save</button>

Confusing Property and Attribute Binding

Avoid using attr. automatically for every value.

Normal element properties generally use:

HTML
<input [value]="name">

Attributes specifically requiring attribute binding use:

HTML
<div [attr.aria-label]="description"></div>

Putting Too Much Logic in the Template

Avoid large calculations and complicated expressions such as:

HTML
{{ calculateSomethingVeryComplex(data, settings, configuration) }}

Templates are easier to maintain when they mainly describe the view.

Prefer exposing meaningful data from the component:

HTML
{{ finalPrice }}

Calling Expensive Methods Repeatedly

This is syntactically valid:

HTML
{{ calculateTotal() }}

But a method used directly in a template may be evaluated repeatedly as Angular updates the view.

For expensive calculations, consider computing or deriving the value more appropriately rather than repeatedly performing substantial work from the template.

Accessing Possibly Missing Objects Directly

Risky:

HTML
{{ user.address.city }}

Safer when the object may not yet exist:

HTML
{{ user?.address?.city }}

Using Two-Way Binding Everywhere

Two-way binding is convenient, but it should not automatically replace clear one-way data flow.

For simple UI display:

HTML
<input [value]="name">

may be enough.

For synchronized editable state:

HTML
<input [(ngModel)]="name">

may be more appropriate.

Choose the mechanism according to the actual requirement.

Template Design Best Practices

Good Angular templates are usually easy to scan without needing to understand large amounts of hidden logic.

Keep templates focused on presentation and interaction.

Prefer:

HTML
<p>{{ finalAmount }}</p>

over putting an entire business calculation directly in HTML.

Use meaningful names:

HTML
<button (click)="submitOrder()">
  Submit Order
</button>

instead of vague method names such as:

HTML
<button (click)="doIt()">
  Submit Order
</button>

Use class binding when an application state represents a reusable CSS state:

HTML
<div [class.invalid]="hasValidationError"></div>

Use template reference variables for small local template interactions:

HTML
<input #searchInput>

<button (click)="search(searchInput.value)">
  Search
</button>

Use optional chaining where data may legitimately be unavailable:

HTML
{{ customer?.address?.city }}

Most importantly, avoid treating the template as a replacement for the component class. The component handles application behavior and state, while the template primarily describes how that state should appear and how the user can interact with it.

Quick Syntax Reference

RequirementAngular SyntaxExample
Display text{{ }}{{ userName }}
Bind property[property][src]="imageUrl"
Bind attribute[attr.name][attr.aria-label]="label"
Bind CSS class[class.name][class.active]="isActive"
Bind style[style.name][style.color]="textColor"
Handle event(event)(click)="save()"
Two-way binding[()][(ngModel)]="name"
Template reference#name#emailInput
Optional access?.user?.name
Null fallback??user?.name ?? 'Guest'

Angular Template Syntax Memory Guide

The major symbols can be remembered by the direction of communication:

Text
{{ value }}
Display a value

[property]="value"
Send component data to the template

(event)="action()"
Send an event from the template to the component

[(ngModel)]="value"
Synchronize both directions

#variable
Create a local template reference

object?.property
Safely access a possibly missing value

Once these patterns are understood, reading larger Angular templates becomes much easier because most template interactions are combinations of the same basic mechanisms.

Key Takeaways

Angular templates extend HTML so that the UI can work directly with application state and user actions.

  • Interpolation displays dynamic text.
  • Property binding sends values to element, directive, or component properties.
  • Attribute binding controls HTML attributes when attribute-level access is required.
  • Class binding dynamically applies CSS classes.
  • Style binding dynamically controls CSS styles.
  • Event binding reacts to user and browser events.
  • Two-way binding keeps supported UI values and component state synchronized.
  • Template expressions calculate values needed by the view.
  • Template statements perform actions in response to events.
  • Template variables provide values within a template context.
  • Optional chaining / safe navigation helps work with possibly unavailable data.
  • Template reference variables provide local references to elements, directives, or components.

The goal is not to put application logic inside HTML. A well-designed Angular template clearly represents the component's state, displays the appropriate data, and connects user actions to the component using the simplest suitable binding mechanism.

Question Hint