Angular data binding is mostly explicit one-way flow in one direction at a time: component state into the DOM, events back into the component, and two-way syntax only as sugar. The useful angle is when property versus attribute binding, or too much two-way binding, creates real production bugs.
Angular data binding: interpolation, property/attribute/class/style, events, and two-way ([(...)])
Production mental model
Angular binding is not “everything is two-way.” Most bindings are one-way in one direction at a time: component state flows into the DOM, events flow back into the component, and [(...)] is just sugar on top. That distinction matters when you debug stale UI, misuse [attr.*] versus real DOM properties, or overuse two-way binding in complex forms.
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 |
Use the relevant interview-question hub first, then move into a concrete study plan before targeted company sets.