Search code examples
angularionic-frameworkionic4ngrx

NGRX multiple subscription issue with Ionic 4


I am using ionic 4 with ngrx. I have a user selector on Page A and Page b both.

export class ComponentA implements OnInit, OnDestroy {

  private readonly ngUnsubscribe: Subject<void> = new Subject<void>();
  user:any;
  constructor(
    private readonly store: Store<AppState>,
  ) { }

ngOnInit(){}

  ionViewWillEnter(): void {
    this.store.select(getUserState)
      .pipe(takeUntil(this.ngUnsubscribe))
      .subscribe((user) => {
        this.user = user;
      });
  }

  ionViewWillLeave(): void {
    this.ngUnsubscribe.next();
    this.ngUnsubscribe.complete();
    getUserState.release();
  }  

Same subscriptions on page b , when i move from page a to b unsubscribe works but then when i move from b to a and then a to b .. subscription on page a doesn't get unsubscribe. If you traverse back 5 times 5 subscription remains on page a.Both pages get notification. I know in ionic previous page remains in stack so onDestroy() never gets called on forward navigation that is why i have put in subscription and unsubscription in ionic lifecyle hooks. Please suggest how to fix this . Thanks in advance.


Solution

  • The problem is that after the very first leave this.ngUnsubscribe is completed, that means next time when ionViewWillLeave is called this.ngUnsubscribe is completed and won't emit the termination signal.

    You can move the complete part to the ngOnDestroy to keep the stream active until real dispose.

    export class ComponentA implements OnInit, OnDestroy {
    
      private readonly ngUnsubscribe: Subject<void> = new Subject<void>();
      user:any;
      constructor(
        private readonly store: Store<AppState>,
      ) { }
    
      ngOnInit(){}
    
      ionViewWillEnter(): void {
        this.store.select(getUserState)
          .pipe(takeUntil(this.ngUnsubscribe))
          .subscribe((user) => {
            this.user = user;
          });
      }
    
      ionViewWillLeave(): void {
        this.ngUnsubscribe.next();
        getUserState.release();
      }
    
      ngOnDestroy(): void {
        this.ngUnsubscribe.complete();
      }
    }