Google+

Friday, July 16, 2021

Using BehaviorSubject in Angular 12 : differences between Observable VS Subject VS BehaviorSubject

 In this article we review how to use BehaviorSubject in Angular 12 : and also the differences between Observable VS Subject VS BehaviorSubject.


Using  BehaviorSubject in Angular 12 : differences between Observable VS Subject VS BehaviorSubject 



A BehaviorSubject is a kind of observable so you can subscribe to messages sent by the PUBLISHER like any other observable. 

However, BehaviorSubject allows you to control the messages as well, and emit messages at observer's will!!

 In addition, BehaviorSubjects are multicast. A Subject or a BehaviorSubject are like an Observable, but can multicast to many Observers, while plain Observables are unicast (each subscribed Observer owns an independent execution of the Observable). 

That way, Subjects are like EventEmitters: they maintain a registry of many listeners.

Upon subscription, BehaviorSubject  returns the last value kept. However, a regular Observable or a Subject, only trigger when they receive an "NEXT" operation.
For this sake, BehaviorSubject  needs a DEFAULT value upon creation, as it must always return a value on SUBSCRIPTION TIME , even if it hasn't received a "NEXT" operation call.

We can retrieve the last value of the subject in a regular non-observable code by using the getValue() method.

The difference between an Observable and a Subject is that it is an observer in addition to being an observable : you can also edit and emit and send values from a Subject in addition to subscribing to it.

Behavior subject can be turned into observable  using the asObservable() method on BehaviorSubject.


This is a BehaviorSubject  example: DEFAULT VALUE + IMMEDIATE MESSAGE ON SUBSCRIPTION:

 

let bsnew BehaviorSubject("1"); 

bs.next("2");

bs.subscribe(value => {
  console.log("Value received : "value);   
  // Subscription got 2 !!!!!!!!!! However, an observable or subject wouldn's have send a message at this stage
});

bs.next("3"); // Subscription got 3
bs.next("4"); // Subscription got 4
  

And this is an example of Subject: NO DEFAULT, NO MESSAGE UNTIL "NEXT" method triggered:


let snew Subject(); 

s.next("2");

s.subscribe(value => {
  console.log("Value received :"value); 
  // Subscription wont get  any message at this point
});

s.next("3"); 
s.next("4");  

  



Example of BehaviorSubject use:


Following is an example of using BehaviorSubject:  here is the app to try
These TWO components pass data one another using a BehaviorSubject from a Service:


1) First, we define the BehaviorSubject on some Service:

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

@Injectable()
export class MyService {
  constructor() {}
  private bs = new BehaviorSubject<string>('default');
  obs$ = this.bs.asObservable();

  editData(newData) {
    this.bs.next(newData);
  }
}


2) Then, we use it on an OBSERVER Component, like this :

import { ComponentOnInit } from '@angular/core';
import { tap } from 'rxjs/operators';
import { MyService } from '../services/my.service';

@Component({
  selector: 'my-two',
  templateUrl: './two.component.html',
  styleUrls: ['./two.component.css']
})
export class TwoComponent implements OnInit {
  datastring;
  newDatastring;
  tapDataany;

  constructor(private svcMyService) {}

  ngOnInit() {
    this.svc.obs$
      .pipe(tap(d => (this.tapData = d)))
      .subscribe(d => (this.data = d));
  }

  UpdateData(user) {
    this.svc.editData(this.newData);
  }
}





3) Then, we use on the template HTML is as follows :

<p>
  Data received on Component TWO : {{data}}
</p>


JSON = {{data | json}}




4) The PUBLISHER will be the component ONE:

import { ComponentOnInit } from '@angular/core';
import { MyService } from '../services/my.service';
@Component({
  selector: 'my-one',
  templateUrl: './one.component.html',
  styleUrls: ['./one.component.css']
})
export class OneComponent implements OnInit {
  datastring;
  newDatastring;

  constructor(private svcMyService) {}

  ngOnInit() {
    // receive data back:
    this.svc.obs$.subscribe(d => (this.data = d));
  }
  UpdateData() {
    // send updated data
    this.svc.editData(this.newData);
  }
}


<p> Data sent from component ONE : <br />
  {{data}}
</p>
<input [(ngModel)]="newData"/>
<button (click)="UpdateData();">Update Data</button>

5) And both components will be used on the App.Component :


<p>
  Publish Data from Component ONE to Component TWO
</p>

<my-one></my-one>
<my-two></my-two>

This way, both components are interconnected and pass the data on the fly each another.
( See the code on   stackblitz.com )



That's All!!! 
This post was about BehaviorSubject in Angular 12 : differences between Observable VS Subject VS BehaviorSubject.
Enjoy Angular.....

      by Carmel Schvartzman

כתב: כרמל שוורצמן