Data Binding in Angular
Question 1: What is Data Binding in Angular and what are its types?
Answer: Data binding in Angular is a mechanism for synchronizing data between the component class and its template. There are four types:
- Interpolation (
{{}}
): One-way from class to template - Property Binding ([property]): One-way from class to template
- Event Binding ((event)): One-way from template to class
- Two-way Binding ([(ngModel)]): Two-way between class and template
Example of all types:
@Component({
selector: 'app-data-binding',
template: `
<!-- Interpolation -->
<h1>{{title}}</h1>
<!-- Property Binding -->
<img [src]="imageUrl">
<button [disabled]="isDisabled">Click me</button>
<!-- Event Binding -->
<button (click)="handleClick($event)">Save</button>
<!-- Two-way Binding -->
<input [(ngModel)]="username">
<p>Hello, {{username}}!</p>
`
})
export class DataBindingComponent {
title = 'Data Binding Demo';
imageUrl = 'path/to/image.jpg';
isDisabled = false;
username = '';
handleClick(event: MouseEvent) {
console.log('Button clicked:', event);
}
}
Question 2: How does Property Binding differ from Interpolation?
Answer: Property Binding binds a property of a DOM element to a component property using [], while Interpolation inserts a component property value into the template using {{ }}
@Component({
template: `
<!-- Interpolation -->
<div>{{message}}</div>
<div title="{{tooltipText}}">Hover me</div>
<!-- Property Binding -->
<div [innerHTML]="message"></div>
<div [title]="tooltipText">Hover me</div>
<!-- When to use which -->
<img src="{{imageUrl}}"> // Works, but not recommended
<img [src]="imageUrl"> // Preferred way
<!-- Property binding required for non-string values -->
<button [disabled]="isDisabled">Click</button>
<div [style.width.px]="width">Sized div</div>
`
})
class BindingComponent {
message = '<b>Hello</b>'; // Will be escaped in interpolation
tooltipText = 'Helpful tip';
imageUrl = 'image.jpg';
isDisabled = true; // Boolean
width = 100; // Number
}
Question 3: How does Event Binding work in Angular?
Answer: Event Binding in Angular allows you to listen for and respond to user actions (like clicks or keystrokes) by binding a DOM event to a component method using (), such as (click)=“handleClick()”.
@Component({
template: `
<!-- Basic event binding -->
<button (click)="onClick()">Click Me</button>
<!-- With event data -->
<input (input)="onInput($event)">
<!-- Multiple events -->
<div (mouseenter)="onHover()"
(mouseleave)="onLeave()">
Hover me
</div>
<!-- Custom events -->
<app-child (userSaved)="onUserSaved($event)">
</app-child>
`
})
class EventComponent {
onClick() {
console.log('Clicked!');
}
onInput(event: Event) {
const value = (event.target as HTMLInputElement).value;
console.log('Input value:', value);
}
onUserSaved(user: User) {
console.log('User saved:', user);
}
}
Question 4: How does Two-way Binding work and when should you use it?
Answer: Two-way Binding in Angular combines Property Binding and Event Binding using [(ngModel)] to keep the component property and the view in sync, and it should be used when you need to both display and update a property simultaneously, such as in forms.
@Component({
template: `
<!-- Two-way binding with ngModel -->
<input [(ngModel)]="username">
<!-- Same as above but expanded -->
<input [ngModel]="username"
(ngModelChange)="username = $event">
<!-- Custom two-way binding -->
<app-counter [(value)]="count">
</app-counter>
`
})
class TwoWayComponent {
username = '';
count = 0;
}
// Custom component with two-way binding
@Component({
selector: 'app-counter',
template: `
<button (click)="increment()">+</button>
<span>{{value}}</span>
<button (click)="decrement()">-</button>
`
})
class CounterComponent {
@Input() value: number = 0;
@Output() valueChange = new EventEmitter<number>();
increment() {
this.valueChange.emit(this.value + 1);
}
decrement() {
this.valueChange.emit(this.value - 1);
}
}
Question 5: What are Template Reference Variables and how do they relate to data binding?
Answer: Template Reference Variables (#var) are used to reference DOM elements or Angular components/directives in a template, allowing direct access to their properties or methods, and they relate to data binding by enabling interaction with the element’s data or state without explicitly binding to the component class.
@Component({
template: `
<!-- Basic reference -->
<input #nameInput>
<button (click)="greet(nameInput.value)">
Greet
</button>
<!-- Component reference -->
<app-child #childComp></app-child>
<button (click)="childComp.doSomething()">
Call child method
</button>
<!-- With directives -->
<form #loginForm="ngForm" (submit)="onSubmit(loginForm)">
<input name="username" ngModel>
</form>
`
})
class TemplateVarComponent {
greet(name: string) {
alert(`Hello ${name}!`);
}
onSubmit(form: NgForm) {
console.log(form.value);
}
}
Common Interview Follow-up Questions:
Q: What is the difference between [attr.] and [prop.] bindings? A: [attr.] binds to HTML attributes, while [prop.] binds to DOM properties. Use [attr.] when you need to set HTML attributes that don’t have corresponding DOM properties.
<div [attr.aria-label]="label"> <input [prop.disabled]="isDisabled">
Q: How do you handle null or undefined values in data binding? A: Use the safe navigation operator (?.) or nullish coalescing operator (??):
{{user?.name ?? 'Anonymous'}} <div [class.active]="isActive ?? false">
Q: How do you optimize data binding for performance? A: Use OnPush change detection, avoid complex expressions in templates, and minimize bindings:
@Component({ changeDetection: ChangeDetectionStrategy.OnPush, template: ` <!-- Compute in component --> <div>{{computedValue}}</div> <!-- Instead of --> <div>{{expensiveComputation()}}</div> ` })
Q: How do you handle form data binding? A: Use Template-driven forms with ngModel or Reactive forms:
// Reactive Form @Component({ template: ` <form [formGroup]="userForm"> <input formControlName="name"> <input formControlName="email"> </form> ` }) class FormComponent { userForm = new FormGroup({ name: new FormControl(''), email: new FormControl('') }); }