Custom Property Binding (& @Input)
Pass data from parent to child components using @Input — custom property binding for reusable components.
Custom Property Binding (& @Input)
@Input() lets a parent component pass data down to a child component via property binding. This is how you make components reusable and configurable.
Defining an @Input
// child: user-card.component.ts
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-user-card',
template: `
<div class="card">
<h3>{{ name }}</h3>
<p>{{ role }}</p>
<span [class.online]="isOnline">
{{ isOnline ? 'Online' : 'Offline' }}
</span>
</div>
`
})
export class UserCardComponent {
@Input() name: string = '';
@Input() role: string = 'Viewer';
@Input() isOnline: boolean = false;
}
Passing Data from Parent
// parent: app.component.ts
export class AppComponent {
userName = 'Alice Johnson';
userRole = 'Developer';
userOnline = true;
}
// parent template:
<app-user-card
[name]="userName"
[role]="userRole"
[isOnline]="userOnline">
</app-user-card>
<!-- Static values (no binding, just strings): -->
<app-user-card
name="Bob Smith"
role="Designer"
[isOnline]="false">
</app-user-card>
Passing Objects
// child component
export class UserCardComponent {
@Input() user!: { name: string; role: string; isOnline: boolean };
}
// child template
<div class="card">
<h3>{{ user.name }}</h3>
<p>{{ user.role }}</p>
</div>
// parent
export class AppComponent {
currentUser = { name: 'Alice', role: 'Admin', isOnline: true };
}
// parent template
<app-user-card [user]="currentUser"></app-user-card>
Using with *ngFor
// parent
export class AppComponent {
users = [
{ name: 'Alice', role: 'Admin', isOnline: true },
{ name: 'Bob', role: 'Designer', isOnline: false },
{ name: 'Carol', role: 'Developer', isOnline: true },
];
}
// parent template — render a card for each user!
<app-user-card
*ngFor="let user of users"
[name]="user.name"
[role]="user.role"
[isOnline]="user.isOnline">
</app-user-card>
Input with Alias
// The property name inside the component can differ from the binding name:
@Input('cardTitle') title: string = '';
// Parent uses the alias:
<app-card [cardTitle]="'My Card'"></app-card>
Responding to Input Changes
import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
export class UserCardComponent implements OnChanges {
@Input() name: string = '';
ngOnChanges(changes: SimpleChanges): void {
if (changes['name']) {
console.log('Name changed from',
changes['name'].previousValue,
'to', changes['name'].currentValue);
}
}
}
Data Flow Direction
Parent Component
│
│ [name]="userName" (property binding)
│ [role]="userRole"
▼
Child Component (@Input properties)
Key Takeaways
@Input()marks a property as receivable from a parent component- Parent uses
[propertyName]="value"to pass data down - Works with primitives, objects, arrays — any data type
- Combine with
*ngForto render lists of configurable components - Use
ngOnChangesto react when input values change - Data flows one-way: parent → child