Skip to main content
Practice Problems

@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

DirectionDecoratorSyntax
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 ready
Premium

A concise answer to help you respond confidently on this topic during an interview.

Finished reading?
Practice Problems