angularngrxangular-redux

After moving state, clearing the state affects the other state


I am new to ngrx and I have a problem with unsubscribing. I am using both the latest versions of Angular and ngrx.

I have CreateState and ModelState. After creating CreateState within a dialogue, I want to copy CreateState to be part of ModelState and then clearing CreateState so the dialogue becomes empty.

For this, I am first receiving the whole state of CreateState and then calling an Action of ModelState for copying.

this.store$.select(CreateSelectors.selectCreateState).subscribe((state: CreateState.State) => {
  this.store$.dispatch(new ModelActions.CreateAction(state));
  this.router.navigateByUrl('/canvas');
});

After I moved to the new page, I am calling an action on CreateState for clearing.

ngOnInit() {
    this.store$.dispatch(new CreateActions.ClearAction());
}

But it seems that the Select Subscription from my first page is still listening, so clearing the CreateState fires the select and again dispatches the ModelActions.CreateAction.

I tried listening just for the .first() Observable or unsubscribing from the Observable but Typescript says there is no function for .first() or .unsubscribe().

Am I getting something wrong? Should I use a different approach for moving and clearing states?


Solution

  • you should run your Code through a pipe, there you can use the first() operator.

    this.store$.select(CreateSelectors.selectCreateState).pipe(
    first(), // should unsubscribe after first iteration
    tap( (state: CreateState) => {
          this.store$.dispatch(new ModelActions.CreateAction(state));
          this.router.navigateByUrl('/canvas');
    })
    ).subscribe();
    

    Or you could set a variable and subscribe to it.

    const subscription = this.store$.select(CreateSelectors.selectCreateState).pipe(
    tap( (state: CreateState) => {
          this.store$.dispatch(new ModelActions.CreateAction(state));
          this.router.navigateByUrl('/canvas');
    })
    );
    
    // if you don't subscribe nothing will happen
    // unsubscribes after first iteration
    subscription.first().subscribe(); 
    

    some documentation:

    live demo of first()

    documentation of first() RxJS Documentation learn-rxjs