In Angular, reusable child components can receive data from a parent using @Input and send events back using @Output with EventEmitter. This pattern helps you create clean, modular, and maintainable UIs where logic is shared across multiple places.
@Input() – Passes data from a parent component to a child component.@Output() – Sends events from a child component back to the parent.EventEmitter – Used with @Output to emit custom events.*ngFor – Renders multiple instances of the child component for lists.Child ➜ Receives Data
A child component marks a property with @Input() to receive data:
[propertyName]="value".Child ➜ Emits Events
A child component marks an EventEmitter with @Output():
this.eventName.emit(data) to notify the parent.(eventName)="handler($event)".The child component shows a single product and emits an event when the user clicks Buy.
// child.component.ts - reusable product item component
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-child',
template: `
<p>Item: {{ item.name }} - Price: {{ item.price }}</p>
<button (click)="buyItem()">Buy</button>
`
})
export class ChildComponent {
@Input() item: any; // Data received from the parent component
@Output() purchase = new EventEmitter<any>(); // Event sent back to the parent
buyItem() {
this.purchase.emit(this.item); // Emit selected item when Buy is clicked
}
}
The parent component passes a list of products to multiple child components and reacts to the purchase event.
// parent.component.ts - using the reusable child component
import { Component } from '@angular/core';
@Component({
selector: 'app-parent',
template: `
<h2>Available Products</h2>
<app-child
*ngFor="let product of products"
[item]="product"
(purchase)="handlePurchase($event)">
</app-child>
`
})
export class ParentComponent {
products = [
{ name: 'Laptop', price: 1000 },
{ name: 'Phone', price: 500 }
]; // Data source passed into child components
handlePurchase(product: any) {
console.log('Purchased:', product); // Handle the event from the child
}
}
products array holds a list of items.<app-child> instance and passes [item]="product".buyItem() method runs in the child component.purchase.emit(this.item).handlePurchase($event) receives the selected product and logs it or updates state (e.g., add to cart).This pattern keeps display logic inside the child and business logic inside the parent.
@Input() item!: Product; and @Output() purchase = new EventEmitter<Product>(); for better type safety.selected, changed, purchase to describe the event meaningfully.@Input() and displays their name and email.*ngFor in a parent component to render a list of user cards from an array of users.@Output() in UserCardComponent that emits when the card is clicked, and handle it in the parent to maintain a “selected users” list.