Data binding is how Angular connects component state (TS) to the template (HTML) and back. It’s mostly one-way (component ➜ view via interpolation/property bindings, view ➜ component via event bindings). Two-way binding is optional syntactic sugar that combines both directions (commonly via forms/ngModel or custom @Input/@Output pairs).
Angular data binding: interpolation, property/attribute/class/style, events, and two-way ([(...)])
Use guided tracks for structured prep, then practice company-specific question sets when you want targeted interview coverage.
Core idea
Angular templates are declarative. You bind values into the DOM and bind events back into the component. Angular then keeps the DOM synced by re-running the template update phase during change detection (triggered by events, async work, input changes, etc.).
Binding kind | Direction | What it binds to | Syntax | Example |
|---|---|---|---|---|
Interpolation | Component ➜ View | Text nodes / attribute text |
|
|
Property binding | Component ➜ View | DOM properties (not HTML attributes) |
|
|
Attribute binding | Component ➜ View | HTML attributes (incl. ARIA, non-property attrs) |
|
|
Class binding | Component ➜ View | CSS classes |
|
|
Style binding | Component ➜ View | Inline styles (+ units) |
|
|
Event binding | View ➜ Component | DOM events or child |
|
|
Two-way binding | Both | Property + event (banana-in-a-box) |
|
|
Property vs Attribute (common interview trap)
[disabled] sets the DOM property (actual runtime behavior). [attr.disabled] sets/removes the HTML attribute string. For ARIA and many “string-only” attributes, you typically use [attr.*]. For real element state, use property binding.
<h2>{{ title }}</h2>
<img [src]="avatarUrl" [alt]="userName" />
<button type="button" [disabled]="isSaving" (click)="save()">
Save
</button>
<input
[value]="query"
(input)="query = ($event.target as HTMLInputElement).value"
[attr.aria-label]="'Search'"
/>
<div [class.error]="hasError" [style.width.px]="panelWidth"></div>
Two-way binding is just sugar[(x)] expands to [x] + (xChange) for custom components. In forms, [(ngModel)] is provided by template-driven forms (requires importing FormsModule).
import { Component, EventEmitter, Input, Output } from '@angular/core';
@Component({
selector: 'app-rating',
template: `
<button type="button" (click)="set(1)">1</button>
<button type="button" (click)="set(2)">2</button>
<button type="button" (click)="set(3)">3</button>
<span>Current: {{ value }}</span>
`
})
export class RatingComponent {
@Input() value = 0;
@Output() valueChange = new EventEmitter<number>();
set(v: number) {
this.valueChange.emit(v);
}
}
// parent template usage:
// <app-rating [(value)]="rating"></app-rating>
// expands to:
// <app-rating [value]="rating" (valueChange)="rating = $event"></app-rating>
What makes the UI update? | Interview-safe answer |
|---|---|
User events | Template events run handlers, state changes, then Angular checks affected views. |
Async work (HTTP/timers/observables/promises) | Angular typically schedules change detection (Zone-based apps) or you trigger it explicitly in zoneless setups. |
Parent input changes | When parent re-renders and updates an input binding, child updates in the next check. |
Common pitfall | What goes wrong | Fix |
|---|---|---|
Heavy expressions in templates | They run often during change detection and can cause jank | Move work to TS and bind to a field/signal/observable result |
No | Template compile/runtime errors | Import |
Using attribute binding for real element state |
| Prefer property binding for element state |
Trying to use two-way binding everywhere | Harder to reason about state flow in complex apps | Prefer one-way data flow + explicit events; use two-way mainly for form-like controls |
Summary |
|---|
Data binding connects TS state and HTML templates; Angular syncs the DOM via change detection. |
Know the full surface area: interpolation, property, attr/class/style, event, and two-way binding. |
Two-way binding is syntactic sugar: |
Interview nuance: property vs attribute binding, and when to use |