Simplest way to share data between two unrelated Components in Angular

Dhananjay Kumar / Tuesday, April 09, 2019

In Angular, it is essential to know how components communicate with each other. If you use a component inside another component, they create a parent child relationship.  In such a scenario, parent and child components communicate to each other in following ways:

  • @Input()
  • @Output()
  • Temp Ref Variable
  • ViewChild and ContentChild

 You can learn in detail about @Input here   and @Output here. In this blog post, you will learn how data can be shared between components that are not related to each other using Angular Service.

To understand this using an example, create a service.  In the service, create a variable called count.  Service will share value of count variable across the components. Before we create count variable, let us talk about requirement again. We want all components to access last updated value of the data shared using the service. 

For this, we have to wrap the count variable in RxJS subjects. To be precise let us use BehaviorSubject.

We are using BehaviorSubject for the following reasons:

  1. Data from the service should be multicasted. Each consumer component should access the same copy of the data. For this purpose, BehaviorSubject is used.
  2. We are not using observables, as they are unicast in nature. Subscribers will have their own copy of data.
  3. BehaviorSubject stores current value. Therefore, component will always read current value of data stored in BehaviorSubject.

Putting everything together, service to share simple data will look like next code listing:

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
 
@Injectable({
    providedIn: 'root'
})
export class AppService {
    counter = 1;
    count: BehaviorSubject<number>;
    constructor() {
 
        this.count = new BehaviorSubject(this.counter);
    }
 
    nextCount() {
        this.count.next(++this.counter);
    }
}

Now components can consume service to access shared data. For example, in a component, service can be consumed as shown in the next listing:

export class Appchild2Component implements OnInit {
 
    count: number;
    constructor(private appsevice: AppService) {
    }
    ngOnInit() {
 
        this.appsevice.count.subscribe(c => {
            this.count = c;
        });
    }
    nextCount() {
        this.appsevice.nextCount();
    }
}

 

We are subscribing to service and reading the value of count in the local variable. In addition, there is a function that  increments the count.  On the template, you can display and increment shared data as shown in the next code listing:

<h2>Count in component2  =  {{ count }}</h2>
<button (click)='nextCount()'>Next Count from component2</button>

In this way, you can consume service in as many components as possible and everywhere they will share the same data from the service. For your reference you can find working stackblitz here:

https://stackblitz.com/github/debugmodedotnet/componnetcommunicationwithservice

 In my opinion, this is the simplest way you can share data between unrelated components in Angular. I am sure there are better ways for more complex scenarios. Please suggest some ideas in the comments below if you know of other options.