Explain the practical difference: interpolation ({{ }}) writes strings into text nodes (and can do string attribute interpolation), while property binding ([...]) sets real DOM properties (booleans/numbers/objects) and is the correct choice for element state (disabled, checked, value, src). Include the common interview trap: interpolation in boolean-ish attributes can produce wrong behavior. Property binding avoids string coercion edge cases; test boolean attributes and template performance.
Interpolation vs property binding in Angular: what actually gets updated (text vs DOM property), and what bugs does it prevent?
Use guided tracks for structured prep, then practice company-specific question sets when you want targeted interview coverage.
Core idea
Both are one-way bindings (component → view), but they update different DOM targets:
• Interpolation updates text (and when used inside attributes, it results in a string attribute value).
• Property binding updates a DOM property (real runtime state) and keeps the correct type (boolean/number/object).
Interview framing: use interpolation for display text; use property binding for element state.
Aspect | Interpolation {{ }} | Property binding [ ] |
|---|---|---|
What it updates | Text nodes (and string attribute interpolation) | DOM properties (runtime state) |
Type behavior | Always becomes a string | Keeps the real type (boolean/number/object) |
Best for | Displaying values in text | Element state/behavior (disabled, checked, value, src, class/style...) |
Where it can appear | Text content, and inside attribute strings | On a property-like target: [disabled], [value], [src], [class.x], [style.*] |
Common trap | Boolean-ish attributes become strings and can behave “always on” | Correct boolean semantics (true/false) |
<!-- Interpolation = display text -->
<h1>Welcome, {{ userName }}!</h1>
<p>Score: {{ score + 10 }}</p>
<!-- Property binding = real element state -->
<button type="button" [disabled]="isDisabled">Submit</button>
<img [src]="profileImageUrl" [alt]="userName" />
<input [value]="query" (input)="query = ($event.target as HTMLInputElement).value" />
Interview trap: boolean attributes
HTML boolean attributes behave by presence. If you do interpolation inside the attribute, you often end up with a string attribute that’s still “present”, which can be wrong.
<!-- ❌ Bug-prone: string attribute interpolation -->
<!-- disabled="false" still counts as present in many cases -->
<button disabled="{{ isDisabled }}">Submit</button>
<!-- ✅ Correct: sets the DOM property boolean -->
<button [disabled]="isDisabled">Submit</button>
<!-- Another common case: form controls -->
<!-- ❌ Sets attribute string; can desync from actual runtime value -->
<input value="{{ name }}" />
<!-- ✅ Sets the DOM property (or better: use forms) -->
<input [value]="name" />
Property vs attribute binding (quick nuance seniors mention)
[prop] sets a DOM property (real behavior). [attr.name] sets/removes an HTML attribute string. For ARIA and non-property attrs, use [attr.*].
<!-- Real element state: property binding -->
<button [disabled]="loading">Save</button>
<!-- ARIA: attribute binding -->
<div [attr.aria-label]="label"></div>
<!-- Class/style are also bindings (properties managed by Angular) -->
<div [class.active]="isActive" [style.width.px]="width"></div>
Common pitfall | What goes wrong | Fix |
|---|---|---|
Using interpolation for element state (disabled/checked/selected) | String attribute semantics cause incorrect behavior | Use property binding: [disabled], [checked], [selected] |
Binding heavy expressions in templates | Runs frequently during change detection; performance/jank risk | Compute in TS (cached field/signal/observable) and bind the result |
Confusing property vs attribute targets | ARIA / non-property attributes don’t work as expected with [prop] | Use [attr.*] for ARIA/attributes; [prop] for state |
Summary |
|---|
Interpolation ({{ }}) is for rendering text; it produces strings (and attribute interpolation is still string-based). |
Property binding ([prop]) sets real DOM properties and preserves types; use it for element state (disabled, value, checked, src). |
Know the nuance: [attr.*] is for attributes (especially ARIA); [class.*]/[style.*] are the right tools for styling. |
Practical scenario
You need to disable a submit button and bind a numeric input value from component state.
Common pitfalls
- Using interpolation for boolean attributes, resulting in "false" strings.
- Binding strings instead of real DOM properties.
- Inconsistent updates when values are objects or arrays.
Property binding is correct for DOM properties. Test by toggling booleans and verifying real DOM values.