Understanding EventEmitter in Angular: A Complete Guide
EventEmitter in Angular is a class used for emitting custom events synchronously or asynchronously, and it is a crucial part of Angular's component interaction mechanism. It allows child components to send data to their parent components. This is especially useful in scenarios where a direct data binding (using @Input
) from parent to child isn't sufficient, particularly when the child component needs to send some data back up to the parent or notify the parent of an event.
Why We Need to Use EventEmitter
Component Communication: In Angular, components often need to communicate with each other. While
@Input
allows data to flow down from parent to child,EventEmitter
with@Output
allows data to flow from child to parent.Custom Events: It enables components to emit custom events. This is useful when you want a component to react to specific actions taken in another component.
Decoupling Components: It helps in decoupling components by reducing the direct dependency between components, making the application more modular and easier to manage.
Real-World Example
Imagine an e-commerce application with a component for a product list and another component for a shopping cart. The product list component displays products, and each product has an "Add to Cart" button.
Objective: When a user clicks "Add to Cart" on a product, the product list component needs to notify the shopping cart component to add the product.
Solution Using EventEmitter:
- Product Component (Child): It emits an event when a product is added to the cart.
- Shopping Cart Component (Parent): It listens for the event and updates the cart accordingly.
Step-by-Step Implementation
- Product Component (Child):
- It has an
@Output()
property that is an instance ofEventEmitter
. - When the "Add to Cart" button is clicked, it emits an event with the product information.
- It has an
// In product.component.ts
import { Component, EventEmitter, Output } from '@angular/core';
@Component({
selector: 'app-product',
template: `<button (click)="addToCart()">Add to Cart</button>`
})
export class ProductComponent {
@Output() productAdded = new EventEmitter<any>();
addToCart() {
const productData = {/* product details */};
this.productAdded.emit(productData);
}
}
- Shopping Cart Component (Parent):
- It listens for the
productAdded
event from the Product Component. - When the event is received, it updates the shopping cart.
- It listens for the
// In shopping-cart.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-shopping-cart',
template: ``
})
export class ShoppingCartComponent {
updateCart(product: any) {
// Logic to add product to cart
}
}
- Parent Component's Template:
- The parent component's template binds the
productAdded
event to theupdateCart()
method.
- The parent component's template binds the
<!-- In parent component's template -->
<app-product (productAdded)="updateCart($event)"></app-product>
This example illustrates how EventEmitter
facilitates component communication in Angular, allowing for a more modular and manageable application structure.