简体   繁体   中英

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() {
  }

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();
  }
}

Assign it to a subscription variable of type Subscription that can be import ed 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 unsubscribe ing from the Observable and Angular will take care of it.

Each Observable.subscribe() returns a subscription. It would be better to create a subscriptions array and add all the subscriptions in it. On destroy of component(ngOnDestroy lifecycle hook), loop through the subscriptions array and call unsubscribe on it.

Doing this you need not to manage different subscription from different subscriber.

You can do something like this

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

 constructor(
 private readerServices: ReaderService
   ) { }

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM