@input and @output decorators in Angular
Component Communication
Angular components communicate through @Input (parent → child) and @Output (child → parent) decorators. This is the primary mechanism for component interaction.
@Input — Parent to Child
typescript
// child.component.ts
@Component({
selector: 'app-user-card',
template: \`
<div class="card">
<h3>{{ name }}</h3>
<p>Age: {{ age }}</p>
<p>Role: {{ role }}</p>
</div>
\`
})
export class UserCardComponent {
@Input() name = '';
@Input() age = 0;
@Input() role: 'admin' | 'user' = 'user';
@Input({ required: true }) id!: string;
}html
<!-- parent.component.html -->
<app-user-card
[name]="user.name"
[age]="user.age"
[role]="user.role"
[id]="user.id"
/>Input Transform
typescript
@Component({ /* ... */ })
export class MyComponent {
@Input({ transform: booleanAttribute }) disabled = false;
@Input({ transform: numberAttribute }) count = 0;
}html
<!-- String "true" → boolean true -->
<app-my disabled count="5" />@Output — Child to Parent
typescript
// child.component.ts
@Component({
selector: 'app-search-box',
template: \`
<input
[value]="query"
(input)="onInput($event)"
(keyup.enter)="onSearch()"
>
<button (click)="onSearch()">Search</button>
<button (click)="onClear()">Clear</button>
\`
})
export class SearchBoxComponent {
@Output() search = new EventEmitter<string>();
@Output() clear = new EventEmitter<void>();
query = '';
onInput(event: Event) {
this.query = (event.target as HTMLInputElement).value;
}
onSearch() {
this.search.emit(this.query);
}
onClear() {
this.query = '';
this.clear.emit();
}
}html
<!-- parent.component.html -->
<app-search-box
(search)="handleSearch($event)"
(clear)="handleClear()"
/>typescript
// parent.component.ts
handleSearch(query: string) {
console.log('Searching for:', query);
}
handleClear() {
console.log('Search cleared');
}Signal-Based Inputs (Angular 17+)
typescript
@Component({ /* ... */ })
export class UserCardComponent {
// Signal inputs (modern approach)
name = input.required<string>();
age = input(0);
role = input<'admin' | 'user'>('user');
// Computed from inputs
isAdult = computed(() => this.age() >= 18);
greeting = computed(() => \`Hello, \${this.name()}!\`);
}Output with output() Function (Angular 17+)
typescript
@Component({ /* ... */ })
export class SearchBoxComponent {
search = output<string>();
clear = output<void>();
onSearch(query: string) {
this.search.emit(query);
}
}Summary
| Direction | Decorator | Syntax |
|---|---|---|
| Parent → Child | @Input() / input() | [property]="value" |
| Child → Parent | @Output() / output() | (event)="handler($event)" |
| Two-way | @Input() + @Output() | [(property)]="value" |
Important:
@Input passes data down from parent to child. @Output with EventEmitter sends events up from child to parent. In Angular 17+, prefer signal-based inputs (input()) and the output() function for better type safety and reactivity. This is Angular's core component communication pattern.
Short Answer
Interview readyPremium
A concise answer to help you respond confidently on this topic during an interview.