Angular, a popular framework for building dynamic web applications, provides powerful tools for component communication. Among these tools, the @Input and @Output decorators are essential for passing data between components. In this blog, we will delve into the workings of these decorators and provide examples to illustrate their usage.
@Input and @Output Decorators?The @Input decorator allows a parent component to pass data to a child component. It binds a property in the child component to a value sent by the parent component. This is crucial for creating reusable and modular components.
The @Output decorator enables the child component to emit events to the parent component. This is typically used to notify the parent component of certain actions or changes in the child component.
@Input and @Output DecoratorsLet's explore a practical example to understand how these decorators work. Imagine we are building a simple shopping cart application with a product list and a cart component.
First, let's create a new Angular project:
ng new shopping-cart cd shopping-cart ng generate component product-list ng generate component cart
Step 2: Using @Input Decorator
In the ProductListComponent, we want to display a list of products passed from the parent component. Here’s how we can do it using the @Input decorator.
product-list.component.ts
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-product-list',
templateUrl: './product-list.component.html',
styleUrls: ['./product-list.component.css']
})
export class ProductListComponent {
@Input() products: any[];
}
product-list.component.html
<ul>
<li *ngFor="let product of products">
{{ product.name }} - {{ product.price | currency }}
</li>
</ul>
app.component.ts (Parent Component)
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
productList = [
{ name: 'Product 1', price: 100 },
{ name: 'Product 2', price: 150 },
{ name: 'Product 3', price: 200 }
];
}
app.component.html
<app-product-list [products]="productList"></app-product-list>
@Output DecoratorNow, let's add the ability to add products to the cart. We'll use the @Output decorator to emit an event when a product is added to the cart.
product-list.component.ts
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-product-list',
templateUrl: './product-list.component.html',
styleUrls: ['./product-list.component.css']
})
export class ProductListComponent {
@Input() products: any[];
@Output() addToCart = new EventEmitter<any>();
onAddToCart(product: any) {
this.addToCart.emit(product);
}
}
product-list.component.html
<ul>
<li *ngFor="let product of products">
{{ product.name }} - {{ product.price | currency }}
<button (click)="onAddToCart(product)">Add to Cart</button>
</li>
</ul>
app.component.ts (Parent Component)
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
productList = [
{ name: 'Product 1', price: 100 },
{ name: 'Product 2', price: 150 },
{ name: 'Product 3', price: 200 }
];
cart = [];
onAddToCart(product: any) {
this.cart.push(product);
console.log('Cart:', this.cart);
}
}
app.component.html
<app-product-list [products]="productList" (addToCart)="onAddToCart($event)"></app-product-list>
In this blog, we have explored the @Input and @Output decorators in Angular, which are essential for effective component communication. The @Input decorator allows data to flow from parent to child components, while the @Output decorator enables child components to emit events to the parent component. By understanding and utilizing these decorators, you can create more modular, reusable, and interactive components in your Angular applications.
Feel free to experiment with these concepts in your projects, and happy coding!