Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular unsubscribe from BehaviorSubject as Observable

I create a BehaviorSubject in one of my services, and using it asObservable to subscribe to it later, but i need to unsubscribe after the controller is destroyed, how can i unsubscribe from it.

Services

import { Observable, BehaviorSubject } from 'rxjs';

  private currentStepObject = new BehaviorSubject<number>(0);
  public currentStepObservable = this.currentStepObject.asObservable();

  constructor(
  ) { }

  public changecurrentStep(step: number): void {
    this.currentStepObject.next(step);
  }

Controller

 import { ReaderService } from '../../../../services/reader/reader.service';

   constructor(
    private readerServices: ReaderService
   ) { }

   ngOnInit() {
     this.initDocumentData();
     this.readerServices.currentStepObservable
      .subscribe((step) => {
        this.currentStep = step;
      });
  }

  ngOnDestroy() {
  }
like image 542
Miguel Frias Avatar asked Sep 17 '18 13:09

Miguel Frias


2 Answers

try takeUntil with helpful inner Subject.

UPDATE: In this case you don't have to manually unsubscribe from each subscription in a component, because you may have a bit more than one inside.

import { ReaderService } from '../../../../services/reader/reader.service';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators'

export class MyComponent implements OnInit, OnDestroy {

  private unsubscribe$: Subject<any> = new Subject<any>();
  constructor(
    private readerServices: ReaderService
  ) { }

  ngOnInit() {
    this.initDocumentData();
    this.readerServices.currentStepObservable.pipe(
      takeUntil(this.unsubscribe$)
    )
    .subscribe((step) => {
      this.currentStep = step;
    });
  }

  ngOnDestroy() {
    this.unsubscribe$.next();
    this.unsubscribe$.complete();
  }
}
like image 72
Maksym Shevchenko Avatar answered Oct 12 '22 23:10

Maksym Shevchenko


Assign it to a subscription variable of type Subscription that can be imported from rxjs and then unsubscribe from it in the ngOnDestroy

import { ReaderService } from '../../../../services/reader/reader.service';
import { Subscription } from 'rxjs';

subscription: Subscription;

constructor(
  private readerServices: ReaderService
) {}

ngOnInit() {
  this.initDocumentData();
  this.subscription = this.readerServices.currentStepObservable
    .subscribe(step => this.currentStep = step);
}

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

OR use async pipe in the template:

import { ReaderService } from '../../../../services/reader/reader.service';

currentStep$;

constructor(
  private readerServices: ReaderService
) {}

ngOnInit() {
  this.initDocumentData();
  this.currentStep$ = this.readerServices.currentStepObservable;
}

And then in the template:

{{ this.currentStep$ | async }}

This way, you won't have to take care of unsubscribeing from the Observable and Angular will take care of it.

like image 31
SiddAjmera Avatar answered Oct 12 '22 23:10

SiddAjmera