The @Input Decorator
The @Input decorator allows a parent component to pass data into a child component through template property binding.
Basic Usage
// child.component.ts
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-child',
template: `<p>{{ message }}</p>`,
})
export class ChildComponent {
@Input() message: string = '';
}
// parent.component.ts
@Component({
selector: 'app-parent',
template: `<app-child [message]="greeting"></app-child>`,
})
export class ParentComponent {
greeting = 'Hello from parent';
}
Input with Default Value
@Component({
selector: 'app-card',
template: `
<div class="card">
<h3>{{ title }}</h3>
<p>{{ description }}</p>
</div>
`,
})
export class CardComponent {
@Input() title: string = 'Untitled';
@Input() description: string = '';
@Input() variant: 'primary' | 'secondary' = 'primary';
}
Input Aliases
An alias lets the parent use a different property name than the internal field:
@Component({
selector: 'app-user-avatar',
template: `<img [src]="avatarUrl" [alt]="altText">`,
})
export class UserAvatarComponent {
@Input('src') avatarUrl!: string;
@Input('alt') altText: string = 'Avatar';
}
<app-user-avatar [src]="user.imageUrl" [alt]="user.name"></app-user-avatar>
Required Inputs (Angular 16+)
@Component({
selector: 'app-alert',
template: `<div class="alert">{{ message }}</div>`,
})
export class AlertComponent {
@Input({ required: true }) message!: string;
}
If a parent does not provide a required input, Angular throws a compile-time error.
Signal-Based Inputs (Modern Angular)
Angular 17+ introduces signal-based inputs as a modern alternative to @Input. They provide reactive semantics with less boilerplate.
input() Function
import { Component, input } from '@angular/core';
@Component({
selector: 'app-card',
template: `
<div class="card">
<h3>{{ title() }}</h3>
<p>{{ description() }}</p>
</div>
`,
})
export class CardComponent {
title = input<string>('Untitled');
description = input<string>('');
variant = input<'primary' | 'secondary'>('primary');
}
Required Signal Inputs
@Component({
selector: 'app-alert',
template: `<div class="alert">{{ message() }}</div>`,
})
export class AlertComponent {
message = input.required<string>();
}
Input with Transform
import { Component, input, booleanAttribute } from '@angular/core';
@Component({
selector: 'app-toggle',
template: `<span [class.active]="isActive()">Toggle</span>`,
})
export class ToggleComponent {
isActive = input(false, { transform: booleanAttribute });
}
@Input vs input()
| Feature | @Input | input() |
|---|---|---|
| Syntax | Decorator | Function call |
| Reactive | No | Yes |
| Required | No (compile error) | input.required() |
| Transform | No | Built-in |
| Default value | = 'default' | input('default') |
| Alias | @Input('alias') | input.alias? |
When to Use Which
- New projects — prefer signal-based inputs
- Existing codebases — @Input is fine; migrate incrementally
- Library authors — signal inputs work in both standalone and NgModule contexts
Quiz
1. How does a parent component pass data to a child component?
2. What is the modern signal-based alternative to @Input?
3. How do you make an input required in Angular 16+?
Flashcards
Question
How do you pass data from parent to child in Angular?
Click to reveal answer
Answer
@Input() decorator or input() signal. Parent binds with [property] syntax in the template.
Question
What is the signal-based alternative to @Input?
Click to reveal answer
Answer
input() — provides reactive semantics. Use input.required() for mandatory inputs.
Question
How do you alias an input?
Click to reveal answer
Answer
@Input('aliasName') — the parent uses the alias in the template binding.
Revision Notes
Key Takeaways
- 1. @Input allows parent-to-child data flow via property binding
- 2. Signal-based input() provides reactive semantics
- 3. Required inputs enforce compile-time safety
- 4. Aliases decouple internal field names from template API
Interview Tips
- • Explain the difference between @Input and input()
- • Be ready to describe when to use required inputs
- • Mention that inputs are checked during change detection
Cheat Sheet
@Input Cheat Sheet
Decorator syntax:
@Input() message: string = '';
@Input({ required: true }) title!: string;
@Input('src') avatarUrl!: string;
Signal syntax:
message = input<string>('');
title = input.required<string>();
Parent template:
<app-child [message]="greeting"></app-child>