@input, @output & EventEmitter In Angular

@input, @output & EventEmitter In Angular

In this article, we will learn how to use @input, @output, and EventEmitter in Angular. These decorators are used to send data from the parent component to the child component and vice versa. @Input specifies the component's input property, which can be changed by the parent component. The @output specifies the output property (event), which is raised by the EventEmitter in the child component. These occurrences are relayed to the parent.

@input, @output & Eventemitter

@input

The input decorator transforms a property into an input property. That is, it is capable of receiving data from the parent component. Property binding is used by the parent component to connect it to a component property. Angular updates the value in the child component whenever the value in the parent component changes.

Example

Consider the component class below:

@Component({
  selector: 'app-customer-detail',
  templateUrl: './customer-detail.component.html',
  styleUrls: ['./customer-detail.component.css']
})
export class CustomerDetailComponent implements OnInit {
  @Input() customer:Customer;
}

On the customer's property, we have an input decorator. The parent component is expected to provide the component's value.

Using the property binding syntax, the parent component provides the customer object. A square bracket is placed around the customer's property. Assign it the template expression (selectedCustomer), which is a parent component property.

<app-customer-detail customer="" selectedcustomer=""></app-customer-detail>

@output

The output property is decorated with the output property. It's set up as an EventEmitter. The data is passed as an argument to the event by the child component, which raises the event. The parent component uses event binding to listen for events and reads the data.

Example

//Declare the property
@Output() customerChange:EventEmitter<customer> =new EventEmitter<customer>();
 
//Raise the event to send the data back to parent
update() {
  this.customerChange.emit(this.customer);
}

The Output property, customerChange, is of the type EventEmitter.

We use the event binding syntax in the parent component to subscribe to the event. Put a () around the event name (customerChange) and a template statement (update($event)) around it. The data in the $event parameter is passed to it.

<app-customer-detail customer="" customerchange="" event="" selectedcustomer="" update=""></app-customer-detail>

Keep in mind that the argument name must be $event.

EventEmitter

The EventEmitter is in charge of raising the event. The @output attribute is typical of the EventEmitter type. The emit() method will be used by the child component to emit an event along with the data.

//Define  output property
@Output() customerChange:EventEmitter<customer> =new EventEmitter<customer>(); 
 
//Raise the event using the emit method.
update() {
  this.customerChange.emit(this.customer);
}

Let's make an app to learn about input, output, and EventEmitter.

@input, @output & Eventemitter Example

There are two parts to the app we created. A list of customers is displayed in the parent component. The user has the option of clicking the edit button, which will display the customer form in a child component. The child component raises the event when the user modifies the records. The occurrence is recorded by the parent. The parent then adds the new information to the list.

Use the following command to create a new application.

ng new InputOutputExample
 
cd InputOutputExample

Create the components customerList and customerDetail. Create a customer class as well.

ng g c customerList
ng g c customerDetail
ng g class customer

Create customer class.

export class Customer {
 
  customerNo: number=0;
  name: string="";
  address: string="";
  city: string="";
  state: string="";
  country: string="";
 
}

The FormsModule is required by the ngModel. As a result, import it and include it in the import information.

Add the following code under the app.module.ts:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms'
 
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { CustomerListComponent } from './customer-list/customer-list.component';
import { CustomerDetailComponent } from './customer-detail/customer-detail.component';
 
@NgModule({
  declarations: [
    AppComponent,
    CustomerListComponent,
    CustomerDetailComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    FormsModule
  ],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule { }

Child Component

In its input property customer, the child component receives an instance of the customer. The parent must use the property binding to set it.

Users can make changes to the customer. When they're done, they'll hit the update button. The customerChange event is triggered by the update method. The customer is passed to the event as an argument. The parent component receives the data and listens to the event.

The CustomerDetailComponent's whole code can be found below.

import { Component, OnInit, Input, Output,EventEmitter } from '@angular/core';
import { Customer } from '../customer';
 
@Component({
  selector: 'app-customer-detail',
  templateUrl: './customer-detail.component.html',
  styleUrls: ['./customer-detail.component.css']
})
export class CustomerDetailComponent implements OnInit {
 
  @Input() customer:Customer = new Customer();
  @Output() customerChange:EventEmitter<customer> =new EventEmitter<customer>(); 
    
  constructor() { }
 
  ngOnInit() {
  }
 
  update() {
    this.customerChange.emit(this.customer);
  }
 
}

The selector for this component is called 'app-customer-detail.'

The input property adorned with Input is the customer property.

@Input() customer:Customer = new Customer();

customerChange is an output property of the EventEmitter type.

@Output() customerChange:EventEmitter<customer> =new EventEmitter<customer>(); 

We raise the event customerChange whenever the user changes the customer. We provide it the updated customer as an argument.

update() {
  this.customerChange.emit(this.customer);
}

The following code is the customer-detail.component.html file.

<p>Customer No : {{customer.customerNo}}</p>
<p>Name        : <input customer.name="" ngmodel="" /></p>
<p>Address     : <input customer.address="" ngmodel="" /></p>
<p>city     : <input customer.city="" ngmodel="" /></p>
<p>state     : <input customer.state="" ngmodel="" /></p>
<p>country     : <input customer.country="" ngmodel="" /></p>
 
<button click="" update="">Update</button>

The ngModel connects the input element to the customer. It's a two-way connection. The component's update() method is tied to the button's click event.

Parent Component

The parent component's job is to show a list of customers. Pass the selected customer to the child component when the user clicks the edit button. Then you must wait for the customerChange event to occur. When the child's data is received, update the customer's list.

Add the customer-list.component.html code as follows.

<h2>List of Customers</h2>
 
<table class="table">
  <thead>
    <tr>
      <th>No</th>
      <th>Name</th>
      <th>Address</th>
      <th>City</th>
      <th>State</th>
      <th>Country</th>
      <th>Edit</th>
    </tr>
  </thead>
  <tbody>
    <tr ngfor="let customer of customers;">
      <td>{{customer.customerNo}}</td>
      <td>{{customer.name}}</td>
      <td>{{customer.address}}</td>
      <td>{{customer.city}}</td>
      <td>{{customer.state}}</td>
      <td>{{customer.country}}</td>
      <td><button click="" customer="" showdetails="">Edit</button></td>
    </tr>
  </tbody>
</table>
 
<h3>Details</h3>
<app-customer-detail customer="" customerchange="" event="" selectedcustomer="" update=""></app-customer-detail>

To loop through the customer list and display the client details, use the ngFor directive.

The click event is captured by this event binding. We pass the customer object to the showDetails method

<button click="" customer="" showdetails="">Edit</button>

The CustomerDetailComponent's selector is app-customer-detail. To convey the selectedCustomer to the child component, we use property binding. The customerChange event is raised by the child component, which we listen to via event binding and call the update method.

The parent component's component code. It employs two techniques update & showDetails

Add the following code under the customer-list.component.ts:

import { Component, OnInit } from '@angular/core';
import { Customer } from '../customer';
import { element } from 'protractor';
import { ObjectUnsubscribedError } from 'rxjs';
 
@Component({
  selector: 'app-customer-list',
  templateUrl: './customer-list.component.html',
  styleUrls: ['./customer-list.component.css']
})
export class CustomerListComponent implements OnInit {
 
  customers: Customer[] = [
 
    {customerNo: 1, name: 'Rahuld Dravid', address: '', city: 'Banglaore', state: 'Karnataka', country: 'India'},
    {customerNo: 2, name: 'Sachin Tendulkar', address: '', city: 'Mumbai', state: 'Maharastra', country: 'India'},
    {customerNo: 3, name: 'Saurrav Ganguly', address: '', city: 'Kolkata', state: 'West Bengal', country: 'India'},
    {customerNo: 4, name: 'Mahendra Singh Dhoni', address: '', city: 'Ranchi', state: 'Bihar', country: 'India'},
    {customerNo: 5, name: 'Virat Kohli', address: '', city: 'Delhi', state: 'Delhi', country: 'India'},
 
  ]
 
  selectedCustomer:Customer = new Customer();
 
  constructor() { }
 
  ngOnInit() {
  }
 
  showDetails(customer:Customer) {
    this.selectedCustomer=Object.assign({},customer)
  }
  
  update(customer:Customer) {
    console.log(customer)
    var cust=this.customers.find(e =&gt; e.customerNo==customer.customerNo)
    Object.assign(cust,customer)
    alert("Customer Saved")
  }
}

The customer is passed as an argument to the showDetails function. We duplicate it and assign it to a certain customer.

The customer is passed by reference because it is an object. Any changes you make to the customer's profile will also be reflected in the customer's collection. Only when we receive data from the youngster do we want to update the customer's information. As a result, we create a copy of the customer and transmit it to the child component.

Passed by Value is used when passing primitive data types like numbers.

Finally, copy the following code into the root component (app.component.html).

<app-customer-list></app-customer-list>

Run the application.

Input Output EventEmitter Example In Angular

Notes on @Input & @Output

You can also include a name as an optional parameter.

We can supply an option name to the input decorator, which we can use while binding in the parent.

As an example,

@Input(‘customerData’) customer:Customer;

Intercept input property changes with a setter

A setter property can also be created.

private _customerData = '';
@Input()
set customer(customer: Customer) {
  //You can add some custom logic here
  this._customerData = customer;
  console.log(this._customerData)
}
get customer(): string { return this._customerData; }

Subscribe to @Input changes using ngChanges

You can also use the ngOnChanges life cycle hook to subscribe to changes.

EventEmitters can be seen.

RxJs Subjects are EventEmitters. As a result, you can alter them using RxJs operators. This link will tell you more about it.

Pass by reference

By reference, the objects are passed. As a result, modifying the object updates the original object. Numbers and other primitive data types are passed by value.

Conclusion

In this tutorial, we'll look at how to use Input, Output, and EventEmitter in Angular. We use them to communicate with the parent and child parts of the system. The @Input & @output decorators are used by the Child component to define the input and output properties. Property binding is used by the Parent to set the input property. When a child component wants to convey data to the parent, it raises an event using EventEmitter. The parent uses event binding to listen to the output property.

I hope this article helps you and you will like it.👍

If you have any doubt or confusion then free to ask in the comment section.

Post a Comment

Previous Post Next Post