Angular component communication by using Input Output decorator

angular 2 communication between sibling components angular 2 sibling component communication angular 2 pass data between components angular 2 component interaction angular 2 component communication @input angular 2 angular 2 child components angular 2 nested components

@Input and @Output decorator ar used to pass data/communicate between components, @input is used to pass data from parent to child component on the other hand @Output is use to notify the parent by using EventEmitter.

Take the simple example of customers list parent page and add/edit child component, on clicking the edit button current customer data need to be passed to the child component to update. After successful Add or Edit, parent component need to notify that data has been updated, so refresh the list.

Let's create a customer model structure:

export class CustomerModel{
    id:number = 0;
    name: string;
    addresss: string;
}

Try to keep it simple so we can more focus on the @input and @Output communication.

We will store data on the localStorage for this example and will create the service for this to add and update the data on localStorage which we will not discuss here but you can check that on the plunker.

Let's create an Add-Edit Component and add following HTML to it:

<fieldset>
  <legend>Add/Edit Customer</legend>
    <form >
      <div class="form-group row">
        <label for="name" class="col-md-1 col-form-label">Name</label>
        <div class="col-md-5">          
            <input type="text" id="name" name='name'
              class="form-control"
              placeholder="Customer Name"
              [(ngModel)]="customer.name">
        </div>
      </div>
      <div class="form-group row">
        <label for="address" class="col-sm-1 col-form-label">Address</label>
        <div class="col-md-5">          
            <input type="text" id="address" name='address'
              class="form-control"
              placeholder="Customer Address"
              [(ngModel)]="customer.address">
        </div>
      </div>
      <div class="form-group row">
        <div class="col-md-5 col-md-offset-1">   
          <input type="submit" class="btn btn-primary" value='Save' (click)='save()'>
          <input type="button" class="btn btn-warning" value='Clear' (click)='clear()'>
        </div>
      </div>      
    </form>
</fieldset>

As simple as two text boxes and two button to save and cancle.

Add Add-Edit Component ts file and following code to it:

import { Component, OnInit, Input, Output,EventEmitter } from '@angular/core';
import { CustomerModel } from '../model/app.models';
import { DataService } from '../services/data.service';

@Component({
  selector: 'add-edit-customer',
  templateUrl: './add-edit-customer.component.html'
})
export class AddEditCustomerComponent implements OnInit {
  @Input() customer: CustomerModel;
  @Output() status = new EventEmitter();

  constructor() { }

  ngOnInit() {
    this.clear();
  }

  save(){
    DataService.save(this.customer);  
    this.clear();  
    this.status.emit(true);
  }
  clear(){
    this.customer = new CustomerModel();
    this.status.emit(false);
  }
}

Now let's see this code part by part to understand:

import { Component, OnInit, Input, Output,EventEmitter } from '@angular/core';
import { CustomerModel } from '../model/app.models';

import { DataService } from '../services/data.service';
  • First we imported Input, Output and EventEmitter to communicate between components
  • CustomerModel: simple customer structure to pass data
  • DataService to save, update and delete data on localStorage

Component decorator nothing new, so no need to explain

@Component({
  selector: 'add-edit-customer',
  templateUrl: './add-edit-customer.component.html'
})

@Input and @Output decorator to accept the data and notify the partent that data is update

@Input() customer: CustomerModel;
@Output() status = new EventEmitter();

Add the Save method:

save(){
    DataService.save(this.customer);  
    this.clear();  
    this.status.emit(true);
}

Save the data, clear the customer model to clear the text boxes and finally raise and event by using status.emit and pass true to indicate that data has been update, please update the list

clear(){
    this.customer = new CustomerModel();
    this.status.emit(false);
}

Just to show the event example we are emiting the event and passing false to indicate that nothing is change.

Now we need to create another component for customer lists where we will use our add-edit component and pass the customer to update, add following HTML to it:

<fieldset>
  <legend>Customer List</legend>      
  <table class="table table-bordered">
    <tr>
      <th>ID</th>
      <th>Customer Name</th>
      <th>Address</th>
      <th>Actions</th>
    </tr>
    <tr *ngFor="let customer of customers">
      <td>{{customer.id}}</td>
      <td>{{customer.name}}</td>
      <td>{{customer.address}}</td>
      <td>
          <i class="fa fa-pencil-square-o fa-lg" 
             style='cursor:pointer' title='Edit'
             aria-hidden="true" (click)='edit(customer)'></i>

          <i class="fa fa-trash fa-lg" 
             style='cursor:pointer'  title='Remove'
             aria-hidden="true" (click)='delete(customer.id)'></i>
      </td>
    </tr>
  </table>

  <div class="well">
    <add-edit-customer [customer]="customer"
        (status)='saveStatus($event)'></add-edit-customer>
  </div>
</fieldset>

First part is simply a ngFor loop to show the list of customer records and second we used our created component, let's see this:

<add-edit-customer 
    [customer]="customer"
    (status)='saveStatus($event)'>
</add-edit-customer>

This is our created component, here we are passing a customer to update by using [customer]="customer", [customer] is the @Input decorator at our add-edit component and "customer" is a local variable to our list component

(status)='saveStatus($event)' we used here our status event from the child component 'add-edit.component' and says we have a method named 'saveStatus' which will keep listening to data update, if anything updates this method will update the list of customer.

Let me copy the complete code of list component and then we can see if there is anything need to explain:

import { Component, OnInit } from '@angular/core';
import { CustomerModel } from '../model/app.models';
import { DataService } from '../services/data.service';
@Component({
  selector: 'customers-list',
  templateUrl: './customers.component.html'
})
export class CustomersComponent implements OnInit {
  customer: CustomerModel;
  customers: Array<CustomerModel> = [];
  constructor() { 
    this.customer = new CustomerModel();
  }

  ngOnInit() {
    this.getCustomers();
  }

  getCustomers(){
      this.customers = DataService.getCustomers();
  }

  edit(record){
    this.customer = Object.assign({}, record) ;
  }

  delete(id){
    DataService.deleteCustomer(id);
    this.getCustomers();
  }

  saveStatus(rStatus){
    if(rStatus== true)
      this.customers = DataService.getCustomers();
  }
}
  • constructor is creating a blank customer model
  • OnInit is used to get customer from service by using the method getCustomers()
  • edit(record): just assigning the local customer variable to the selected customer record, which will automatically will be passed to add-edit child component by using the @input decorator
  • delete(id): just delete the record from localStorage and refreshing the list

saveStatus: it will keep listening to the status event of child component, and check the status, if it it returns true, get the data from the service to refresh the list:

saveStatus(rStatus){
   if(rStatus== true)
     this.customers = DataService.getCustomers();
}

There are many otherways to communicate between components like service, local variable (#variableName) but we discuss here only the @Input, @Output decorator and EventEmitter. Go and play with plunker to see the feature and easiest way of communication in Angular.

Ali Adravi Having 13+ years of experience in Microsoft Technologies (C#, ASP.Net, MVC and SQL Server). Worked with Metaoption LLC, for more than 9 years and still with the same company. Always ready to learn new technologies and tricks.
  • angular2
  • angularjs
  • input
  • output
By Ali Adravi On 30 Sep, 17  Viewed: 2,167

Other blogs you may like

Angular 4 upload files with data and web api by drag & drop

Upload file with data by clicking on button or by drag and drop, is the topic of this article. We will try to create an image gallery by uploading files and save data into database and images into a folder. We will try to create a component in a way that it can be used anywhere in entire... By Ali Adravi   On 24 Sep 2017  Viewed: 41,048

Angular 2 CRUD with Web API 2

Angular 2 insert update, delete, search, sort feature we will try in this article which we will improve with dynamic component loading and image upload with drag and drop feature in coming articles with the same base code. We are going to use Angular-CLI 4 for this application. What we need to... By Ali Adravi   On 03 Sep 2017  Viewed: 25,754

Angular 2 Dynamically Add & remove Components

Angular 2 gives full control to add or remove component in other component programmatically by simple steps. In this article we are going to see how to add, remove experience component to any other component, we will also try to pass some values to component from parent to child component to see if... By Ali Adravi   On 27 Aug 2017  Viewed: 50,515

Angular 2 Accordion expand only one at a time

Createing accordion demo in Angular 2 is more than easy, Angular have rich of conditional features which we will see in this article, like how to apply more than one class on the basis of some conditional values. For this demo we are not goign to write some fancy CSS and animation but use the... By Ali Adravi   On 19 May 2017  Viewed: 11,975

Angular 2 Page Title Static and Dynamic with built-in Title Service

Angular 2 have a built-in service called Title, while in angularjs or angular 1 we were maintaining it through the routing or through the service. By using the Title service provided by Angular 2, in 2 minute every thing will be set without any complication, even we don't need to understand the... By Ali Adravi   On 14 Apr 2017  Viewed: 5,047