0

This can't be the only way to unsub Behavior Subjects :

  maxSub;
  fromSub;
  toSub;
  pageNumberSub;
  originalMaxSub;
  selectionSub;
  selectionOfInterestSub;

  constructor(private store: StoreService) {}

  ngAfterContentChecked(){
    this.maxSub = this.store.max$.subscribe((max) => {
      if(max !== null && max !== undefined){
        this.max = max;
        this.maxPages = Math.floor(this.max / Variables.to);
        this.pages = Array.from(Array(this.maxPages), (x, i) => i + 1);
      }
    }, (error) => console.log(error), () => {});

    this.fromSub = this.store.from$.subscribe((from) => {
      if(from !== null && from !== undefined) {this.from = from; this.split = this.to - (this.from - 1)}
    }, (error) => console.log(error), () => {});

    this.toSub = this.store.to$.subscribe((to) => {
      if(to !== null && to !== undefined) {this.to = to; this.split = this.to - (this.from - 1)}
    }, (error) => console.log(error), () => {});

    this.pageNumberSub = this.store.pageNumber$.subscribe((pageNumber) => {
      if(pageNumber !== null && pageNumber !== undefined) {this.page = pageNumber;}
    }, (error) => console.log(error), () => {});

    this.originalMaxSub = this.store.originalMax$.subscribe((originalMax) => {
      if(originalMax !== null && originalMax !== undefined) {this.originalMax = originalMax;}
    }, (error) => console.log(error), () => {});

    this.selectionSub = this.store.selection$.subscribe((selection) => {
      if(selection !== null && selection !== undefined) this.selectedAmount = selection.length;
    }, (error) => console.log(error), () => {});

    this.selectionOfInterestSub = this.store.selectionOfInterest$.subscribe((selectionOfInterest) => {
      if(selectionOfInterest !== null && selectionOfInterest !== undefined) this.selectionOfInterest = selectionOfInterest;
    }, (error) => console.log(error), () => {});
  }

  ngOnDestroy(){
    this.maxSub.unsubscribe();
    this.fromSub.unsubscribe();
    this.toSub.unsubscribe();
    this.pageNumberSub.unsubscribe();
    this.originalMaxSub.unsubscribe();
    this.selectionSub.unsubscribe();
    this.selectionOfInterestSub.unsubscribe();
  }

in regular old Observables you can just :

alive = true;

constructor(private store: StoreService) {}

  ngAfterContentChecked(){
     this.store.thing.subscribe().takeWhile(this.alive)...
  }

  ngOnDestroy(){
    this.alive = false;
  }

which is much simpler.

Isn't there a way to do the same with Behavior Subjects?

Another thing : am I missing a fundamental property of Behavior Subjects that they only subscribe once within an class no matter how many times the subscribe is called and that's why there's no such thing as takeWhile() on Behavior Subjects?

tatsu
  • 2,316
  • 7
  • 43
  • 87

1 Answers1

1

1 - Actually what you call it a simpler way does not unsubscribe at all it just stop reading what comes from the observable. So either use unsubscribe or complete.

2 - Since you are unsubscribing at the same time and you clearluy don't use the Subject for anything else, then it's fine to use the same Subject variable for all your subs and then you can unsubscribe with oneline of code and you don't need to initialize all these Subject instances.

Taha Zgued
  • 1,088
  • 12
  • 18
  • are you saying it should be `ngOnDestroy(){this.sub.complete()}` instead of `ngOnDestroy(){this.sub.unsubscribe()}` ? – tatsu Jul 12 '18 at 07:15
  • 1
    What I'm saying is it should be this.sub.unsubscribe() instead of this.alive = false; About this.sub.next() this.sub.complete(); it's another way to unsubscribe where you are using takeWhile. check this post https://blog.codecentric.de/en/2018/01/different-ways-unsubscribing-rxjs-observables-angular/ – Taha Zgued Jul 12 '18 at 08:52
  • is it necessary to worry about unsubscribing at all in this context : a component that starts listening to behavior subjects in order to get it's various number variables? – tatsu Jul 12 '18 at 12:08
  • 1
    Well yea, if don't unsubscribe and the event does not complete or error out then the next function will continue to be called and you will end up with many subscribition Objects around which is kinda massy (if that's the right word here) and effects the memory. And here you kinda ignoring the hole advantage of Observebals over promises – Taha Zgued Jul 12 '18 at 14:07
  • hey I can't get it to work anymore. what's the correct syntax? – tatsu Jul 31 '18 at 12:11
  • ok ,so, declaring the global var as a `Subscription` from `import { Subscription } from 'rxjs';` makes it work for me. – tatsu Jul 31 '18 at 13:03
  • in the end it actually doesn't do what you say, it replaces the variables content with the new sub so it doesn't unsubscribe all only the last one, could you take another look? – tatsu Aug 13 '18 at 09:17
  • okay, here's my final take : declare you variable as an array : `sub = [];` subscribes happen not within an attribution but a push : `this.sub.push( ...behavior subject as observable subscribed... )` , then during the `onDestroy`, unsubscribe withing a forEach : `this.sub.forEach(x=> x.unsubscribe())` – tatsu Aug 13 '18 at 09:35