Friday, September 29, 2017

Communication between Sibling components in Angular

Communication or data exchange between component is pretty common scenario in angular development. We know the property binding and event binding can be implemented for hierarchical communication, i.e to pass data from parent to child component and vice versa. We can implement common service scenario when there is need to communicate among sibling components.

Now, the question is can we implement same solution for parent child communication? The answer is yes, we can because service in angular is singleton in nature. So, it is single source of truth.
Now, let’s implement common service scenario as example.

Step 1) Create multiple component and subscribe common service in target component

Here is example code for that. We will create “SharedService” shortly. Here is code for “Work1” component.

import { Component } from '@angular/core';
import { SharedService } from '../services/SharedService'

@Component({
  selector: 'work1',
  template: `
  <input type="text" name="txtName" [(ngModel)]="name">
  <input type="button" name="Click" value="Click" (click)="refresh()">`
})

export class Work1 {
  name : string;
  constructor(private _sharedService: SharedService ){

  }
  refresh(){
    this._sharedService.publishData(this.name);
  }

}


Here the idea is, when user will click refresh, it will call one function in shared service. The function is responsible to push the data in an observable stream. As soon as service will push the data to stream, the subscriber of the stream will get notification.

Let’s create another component called “Work2”

import { Component } from '@angular/core';
import { SharedService } from '../services/SharedService'

@Component({
  selector: 'work2',
  template: `{{name}}`
})
export class Work2 {
  name : string;

  constructor(private _sharedService : SharedService){

    this._sharedService.name$.subscribe(
      data => {
          this.name = data;
      });
  }
}


Here, you can see that we are subscribing “name” observable in SharedService.  So, when there will be any change of “name” variable then the code within constructor should trigger.

Step2) Create common service.

Now, we will implement the common service which will function as mediator/event publisher in implementation.

import { Injectable } from '@angular/core';
import { Subject }    from 'rxjs/Subject';

@Injectable()
export class SharedService {

  private name = new Subject<string>(); 
  name$ = this.name.asObservable();

  publishData(data: string) {
    this.name.next(data);
  }

}

The pushData() function is responsible to push the current data to “name$” observable stream.
So, here is final output