In our application, we have a page that should only be navigated to if a certain state is set, let's call it requiredState$ on Page C.
A user has to chose some values on it's way to said page, by doing so he sets the requiredState$ on Page B. The user can start this selection cycle mutliple times, meaning that he will navigate multiple times to Page C. Starting point is Page A. Upon navigation from Page A to Page B, the state is resetted.
The order is Page A (reset states) -> Page B (select state) -> Page C (require state) -> Page A and so on.
To avoid navigation to Page C without without requiredState$ being set, we have following check in our pipe on Page C:
this.intermediateObservable$ = this.requiredState$.pipe(
tap((requiredState) => {
if (!requiredState) {
// navigate back to Page B (*)
this.cancelPipe$.next();
}
}),
// ...
takeUntil(this.cancelPipe$),
// ...
);
whereas cancelPipe$ is a simple Subject.
The Observable this.intermediateObservable$ is used in three places
To produce the displayed data
this.data$ = this.intermediateObservable$.pipe(...)which then is subscribed by
asyncpipe in the HTML templateWhen the user selects a category
this.intermediateObservable$.pipe(
take(1)
).subscribe((someData) => {
// filter out desired category and save to state service
});
- When the user wants to display informational data
this.modalContent$ = this.intermediateObservable$.pipe(
// map information to show
);
Again, this.modalContent$ is passed via async pipe to a modal
Problem
In the first cycle, everything is fine. The user sets the state on Page B, navigates to Page C to do some more things, and goes back to Page A. Now if he starts the second cycle, he navigates to Page B (which just before navigation, resets the required state). This seems to trigger the marked line (*) from Page C, resulting in a "double navigation" to Page B.
How is this even possible? I am aware that pipe() creates a new observable, meaning there are three of them.
- and 3. are not subscribed directly to, but later via
asyncpipe, which should be handled autoatically. - uses the
take(1)operator, which in my understanding should directly unsubscribe afterwards.