Angular component communication using Subject(observable)

Angular component communication using Subject(observable)

In this tutorial, we are going to learn about how to communicate between components in angular using Subject observable.

Subject

A Subject is a special kind of observable which can act as both observer and observable it means we can publish the data using Subject and also access the data

Subject is also a multicast observable it means each observable can have many observers(subscribers) while normal observables are unicast.

Component communication

In angular, we normally communicate between components using @Input and @Output decorators but it is somewhat hard to remember. If you don’t know about it checkout my previous tutorial.

Now open your angular app and create a new file called message.service.ts and add the below code.

message.service.ts
import { Subject } from 'rxjs';import { Injectable } from '@angular/core';

@Injectable({
    providedIn: 'root'
})

export class MessageService {    private subject = new Subject();

    sendMessage(msg) {        // it is used to publish data         this.subject.next(msg);    }
    accessMessage() {        // asObservable helps us to prevent the        // leaks of Observable from outside of the subject        return this.subject.asObservable();    }}

In the above code,we first imported Subject constructor from the rxjs library and added it to the subject property.

Inside sendMessage method we are accessing the subject observable and invoking the next method to publish the new data.

Sending data

Now in our App component, we are using MessageSerive to send the data to other components.

app.component.html
<div class="center">
  <input [(ngModel)]="msg" placeholder="Enter message" />  <button (click)="addMessage()">Add message</button>
  <app-child></app-child></div>
app.component.ts
import { Component} from '@angular/core';
import { MessageService } from './message.service';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent {
  msg;
  constructor(private msgService: MessageService) { }
  addMessage() {
    this.msgService.sendMessage(this.msg);    this.msg = '';
  }
}

Accessing the data from child component

Now we can access the AppComponent messages from the ChildComponent by subscribing it.

child.component.html
<ul>
    <li *ngFor="let msg of msgList">{{msg}}</li></ul>
child.component.ts
import { Component, OnInit } from '@angular/core';
import { MessageService } from '../message.service';
@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
  msgList = [];  subscription;
  constructor(private msgService: MessageService) { }

  ngOnInit() {
   this.subscription = this.msgService.accessMessage().subscribe(      (msg) => {        this.msgList.push(msg);      }    );  }

   ngOnDestroy() {
    this.subscription.unsubscribe();
  }
}

passing-data-example

In your case, if you need to access the data from more than one component you can do it by creating multiple subscriptions and don’t forget to call unsubscribe method when a component destroys, otherwise, observables are active and create memory leaks in your app.