Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid infinite loop while updating self in a BehaviorSubject?

Declared like this:

  public panel$: BehaviorSubject<any> = new BehaviorSubject<any>(false);

Used like this

  togglepanel() {
    this.panel$.subscribe(
      (x) => {
        if (x) {
          this.panel$.next(false);
        } else {
          this.panel$.next(true);
        }
      });
  }

It creates an endless cycle trying to update self.

like image 601
ishandutta2007 Avatar asked Sep 19 '25 17:09

ishandutta2007


1 Answers

You can update it by taking only one(latest) value from the panel$ Observable:

this.panel$.take(1).subscribe(...)

But it is better to model your state a bit differently, like this:

// const onToggle$ = new Rx.Subject();
var toggle$ = Rx.Observable.fromEvent(document, 'click');

const initialValue = true;
const state$ = toggle$
  .scan(state => !state, initialValue)
  .startWith(initialValue);
      
const htmlSubscription = state$.subscribe(state => {
  document.getElementById('toggle').innerText = 'toggle: ' + state;
});
<script src="https://unpkg.com/rxjs/bundles/Rx.min.js"></script>
<button id="toggle">loading...</button>

EDIT:

Angular version of this code is:

  public toggle$ = new Subject();
  public state$ = this.toggle$.scan(state => !state, true)
                        .startWith(true)
                        .subscribe((x) => console.log('x:' + x));


  togglepanel() {
    this.toggle$.next(null);
  }
like image 70
Oles Savluk Avatar answered Sep 23 '25 11:09

Oles Savluk