Open In App

Establish communication between sibling components in Angular 11

Last Updated : 23 Feb, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

In this article, we will see how we can pass data between sibling components on client machine. 

In Angular, we divide our web page into multiple components and the relation among these component forms a tree like structure. A component may have a parent and multiple children. That said, it can also have siblings. In some situations we need to pass data among these independent components. Passing the data is easy, and it makes our code cleaner and more readable while working on a large project.

Prerequisites: NPM must be preinstalled.

To understand how it works, see the diagram below:

  • In case of a user event, we can emit data from one component.
  • This data will be sent to the parent component.
  • The parent component can further transfer this data in form of an input to the other child component.
  • It is a one way transmission, but we can use it the other way in order to make a two-way communication channel.

In Angular, we can achieve this using its inbuilt features:

  • The @Output decorator helps in emitting the data through an EventEmitter<T> object. We will see its working through the example.
  • The parent component will catch the data as $event variable. It can use it in a method or transmit it by other means.
  • Finally the @Input() decorator uses a variable and any input through the parent will get stored in this variable.

Lets see all of this through a simple example. In this post we will see a simple web page that takes keywords as user input in one component and displays the matching rows in other component.

Lets setup the environment first:

  • Install angular cli. Run as administrator or use sudo in case of permission errors.
npm i -g @angular/cli
  • When angular CLI is installed, start a new project using the following command:
ng new <project-name>
  • Now test it using:
ng serve -o
  • If the angular landing page can be accessed on http://localhost:4200, the setup is successful. Clear the content of app.component.html before moving further.
  • After that generate two new components :
ng generate component search
ng generate component table
  • You will see two directories ‘search’ and ‘table’ in the app folder. Both of them will have 4 new files in each.

Lets make our search component and emit an event from it. First in search.component.html write the following code:

HTML




<br><br>
<div>
    <label for="search">Enter the text</label>
    <br>
    <br>
    <input type="text" id="search" placeholder="type some words" 
           (keyup)="emit(keyword.value);" #keyword>
</div>


In above code, there is a simple input field which uses an emit() function when keyup event occurs. We will use this to emit the keyword to parent component. Lets define this method and event in search.component.ts:

Javascript




import { Component, EventEmitter, OnInit, Output } 
        from '@angular/core';
  
@Component({
  selector: 'app-search',
  templateUrl: './search.component.html',
  styleUrls: ['./search.component.css']
})
export class SearchComponent implements OnInit {
  
  constructor() { }
  ngOnInit(): void {
  }
  @Output() emitter:EventEmitter<string>
       = new EventEmitter<string>();
  
  emit(keyword){
      this.emitter.emit(keyword);
  }
}


The emitter object of type “string” will emit the specified parameter in its emit() method. On keyup event, the emit() method executes emitter object’s emit() method.

Now lets populate the code in table.component.ts:

Javascript




import { Component, DoCheck, Input, OnInit } from '@angular/core';
  
@Component({
  selector: 'app-table',
  templateUrl: './table.component.html',
  styleUrls: ['./table.component.css']
})
export class TableComponent implements OnInit, DoCheck {
  data = [
    {name:"Liam", age:"20", post: "Marketing Coordinator"},
    {name:"Noah", age:"25" , post:"Medical Assistant"},
    {name:"Oliver", age:"22", post:"Web Designer"},
    {name:"William", age:"20", post:"Dog Trainer"},
    {name:"Bill", age: "22", post:"President of Sales"},
    {name:"James", age: "19", post:"Project Manager"},
  ];
  items = [];
  constructor() { }
  @Input() keyword:string;
  
  ngOnInit(): void {
    this.refresh();
  }
  
  ngDoCheck(){
    this.refresh();
  }
  
  refresh(){
    this.items = [];
    this.data.forEach(
      item => {
        if(item.name.search(this.keyword) != -1
         || item.age.search(this.keyword) != -1 
         || item.post.search(this.keyword) != -1) {
          this.items.push(item)
        }
      }
    
  }
}


We have declared a data object that is some static data for our table for this example. 

  • The “keyword” variable is defined as Input to this component using @Input() decorator.
  • We have declared a refresh() method that populates the items list using if the content is matched in either of the field with the “keyword” variable.
  • We have called this method in ngDoCheck and ngOnInit methods (Note that we have to implement the interface for them). ngDoCheck method is called post change detection in the app. Hence whenever the keyword changes in parent, this method will replace the list.
  • We will show this list on the table.component.html using the below code:

HTML




<p *ngIf="!items.length">No results found</p>
  
<table class="table" *ngIf="items.length">
    <thead >
        <td>Name</td>
        <td>Age</td>
        <td>Post</td>
    </thead>
    <br>
    <tr *ngFor="let item of items">
        <td>{{item.name}}</td>
        <td>{{item.age}}</td>
        <td>{{item.post}}</td>
    </tr>
</table>


Above code displays the table present in “items” array. Now lets write the code for the parent component app.component.ts:

Javascript




import { Component } from '@angular/core';
  
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'GeeksForGeeks';
  keyword = "";
  send(keyword){
    this.keyword = keyword;
  }
}


In the above code:

  • We have declared a keyword variable.
  • The send() method takes the keyword as parameter and sets it to the class variable.
  • We will use the class variable “keyword” as an input to table component.
  • The event emitted by search component will be handled by send() method.
  • See the code below for app.component.html:

HTML




<div>
  <app-search (emitter)="send($event)"></app-search>
</div>
<hr>
  
<div>
  <app-table [keyword]="keyword"></app-table>
</div>


In this code:

  • “$event” variable represents the emitted data from search component.
  • The table component’s keyword variable is passed as [keyword].

Now save all the files and test the code using:

ng serve -o

On http://localhost:4200 we can see the result.

Output:



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads