In this tutorial we'll see what is output() function in Angular and how to use it for facilitating child to parent communication.
output() in Angular
Angular output() function was released in version 17 and it is designed to be used in place of @Output decorator in Angular. This output() function also provides functionality to emit values to parent directives and components.
Angular output() function returns an OutputEmitterRef object which has two methods emit and subscribe which can be used to emit values to parent directives or components.
How to use output()
First thing is to import output from @angular/core.
import { output } from '@angular/core';
Inside your child component declare a variable and initialize it by calling the output() function. You can optionally specify the type of data the output will emit using a generic.
message = output<string>();
Then you can call emit() method on the declared output to send data to the parent component.
this.message.emit('hello');
In the parent component's template you can use event binding to bind to this emit event.
<app-child (message)="receiveMessage($event)"></app-child>
output() in Angular examples
1. In the first example we'll have a child component where we take input from the user and that input value is then send to the parent component using output().
child.component.ts
import { Component, output } from "@angular/core";
@Component({
selector:'app-child',
templateUrl: './child.component.html',
standalone:false
})
export class ChildComponent{
message = output<string>();
sendMessage(value: string){
this.message.emit(value);
}
}
child.component.html
<div> <input type="text" id="msgInput" #msgInput/> <button (click)="sendMessage(msgInput.value)">Submit</button> </div>
On the click of the button, value of the input which is referenced using a template reference variable (#msgInput) is passed to the bound method.
parent.component.ts
import { Component } from "@angular/core";
@Component({
selector:'app-parent',
templateUrl: './parent.component.html',
standalone:false
})
export class ParentComponent{
message:string='';
recvMessage(msg: string){
this.message = msg;
}
}
Value which is received from the child component is assigned to the message variable.
parent.component.html
<app-child (message)="recvMessage($event)"></app-child>
{{message}}
2. Let's say we have an array of Product objects and we want to use a presentational component (a child component) to display product data, where product data is passed from a container component (parent component). Container component also has methods to increment or decrement the product quantity, event handling for incrementing or decrementing is done through the output() function.
This example shows how to use signals, input() and output() together to write Angular code.
Model Class (product.model.ts)
export class Product{
id: number;
name: string;
price: number;
quantity: number;
constructor(id: number, name: string, price: number, quantity: number){
this.id = id;
this.name = name;
this.price = price;
this.quantity = quantity;
}
}
productssignal.component.ts (parent component)
export class ProductsSignalComponent{
products = signal<Product[]>([
new Product(1, 'Laptop', 1000, 1),
new Product(2, 'RAM', 30, 5),
new Product(3, 'Mouse', 15, 4),
new Product(4, 'Headphones', 200, 3),
]);
grandTotal = computed(() => {
return this.products().reduce((sum, product) => {
const productTotal = product.price * product.quantity;
return sum + productTotal;
}, 0);
});
decrementQuantity(index: number){
this.products.update(products => {
if(products[index].quantity > 0){
products[index].quantity--;
}
return [...products];
});
}
incrementQuantity(index: number){
this.products.update(products => {
products[index].quantity++;
return [...products];
});
}
}
productssignal.component.html
<app-signalproduct [productList]="products()" [grandTotal]="grandTotal()" (decrement)="decrementQuantity($event)" (increment)="incrementQuantity($event)"/>
Here you can see how properties in child component, which are defined as input(), are bound using property binding and properties, which are defined as output(), are bound using event binding.
productsignal.component.ts (Child Component)
import { Component, input, output } from "@angular/core";
import { Product } from "../models/product.model";
@Component({
selector:'app-signalproduct',
templateUrl: './productsignal.component.html',
standalone:false,
})
export class ProductSignalComponent{
productList = input.required<Product[]>();
grandTotal = input.required<number>();
decrement = output<number>();
increment = output<number>();
decrementQ(index:number){
this.decrement.emit(index);
}
incrementQ(index:number){
this.increment.emit(index);
}
}
In the component there are two properties defined as input() to get product data and grand total from the parent component. There are also two properties to send index of the product element whose increment or decrement button is clicked. How these properties are bound to the parent component can be seen in the productssignal.component.html
productsignal.component.html
<h1>Product List </h1>
<table border="1">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Price</th>
<th>Quantity</th>
<th>Total Price</th>
</tr>
</thead>
<tbody>
@for(product of productList(); track product.id; let i = $index){
<tr>
<td>{{ product.id }}</td>
<td>{{ product.name }}</td>
<td>{{ product.price }}</td>
<td><button (click)="decrementQ(i)">-</button>{{ product.quantity}}<button (click)="incrementQ(i)">+</button></td>
<td>{{ product.price * product.quantity}}</td>
</tr>
}
</tbody>
<tfoot>
<tr>
<td colspan="4"><strong>Grand Total:</strong></td>
<td><strong>{{ grandTotal() | currency:'USD' }}</strong></td>
</tr>
</tfoot>
</table>
That's all for this topic output() Function in Angular With Examples. If you have any doubt or any suggestions to make please drop a comment. Thanks!
>>>Return to Angular Tutorial Page
Related Topics
You may also like-

No comments:
Post a Comment