Reputation: 826
I have a NGRX effect inside a feature module that gets lazy loaded when navigating on a certain page.
This effect uses an action that is independent from this feature module but that's emitted after some authentication logic from inside another feature module.
When exiting from that route I wanted to avoid running that NGRX effect since I have no use to keep subscribing to that event. To do that I used the takeUntil
operator in order to unsubscribe the effect after some specific "exit" action, like this:
afterSomeAuthLogicEffect$ = createEffect(() => this.actions$.pipe(
ofType(authActions.someLoginSuccess),
mergeMap(() => {
return this.myService.doSomethingWhileInThisRoute()
.pipe(
map(() => featureModuleActions.ok()),
catchError((error) => featureModuleActions.error(error))
);
}),
takeUntil(this.actions$.pipe(
ofType(featureModuleActions.loadExitRoute)
))
))
After triggering loadExitRoute
this method works fine and the effect is no more subscribed.
The issue is that, when I navigate again on the same feature route, the afterSomeAuthLogicEffect
is not re-subscribed and it does not re-subscribe to the auth action.
I was expecting that after the navigation the effects would be reinitialized but it seems not.
Is there any way to force the re-subscription of the effect? Maybe I have to re-create the effect inside some specific lifecycle method?
Upvotes: 0
Views: 712
Reputation: 15505
You can use repeat
RxJS operators with the delay
option (previosly repeatWhen
operator) for this task.
Given your example, something like this:
afterSomeAuthLogicEffect$ = createEffect(() => this.actions$.pipe(
ofType(authActions.someLoginSuccess),
mergeMap(() => {
return this.myService.doSomethingWhileInThisRoute()
.pipe(
map(() => featureModuleActions.ok()),
catchError((error) => featureModuleActions.error(error))
);
}),
takeUntil(this.actions$.pipe(
ofType(featureModuleActions.loadExitRoute)
)),
repeat({
delay: () => this.actions$.pipe(
ofType(RELOAD_PAGE_EVENT),
filter((a) => a.payload.event.url.includes('/YOUR_FEATURE_URL'))
)
}),
))
This operator allows to resubscribe to a source when the source completes in order to keeping the subscription alive.
Inside the repeat({ delay })
you can return an observable that emits whenever you want to resubscribe after the takeUntil
completes the source. In your case you can listen to routes events or any subscribable lifecycle event in order to "reload" the effect.
https://rxjs.dev/api/operators/repeat
Upvotes: 3