I am currently building an application using NgRx and the Router Store. There is a dropdown in one component, that changes params in the url and navigates on the same component. Since navigating on the same component doesn't call NgOnInit the corresponding effect (that calls the API) is not called. In my opinion, the effect should always be called if component has changed the params.
loadTransactions$ = createEffect(() => this.actions$.pipe(
ofType(
NavigationActions.ActionType.NavigateToTransactionsSuccess,
TransactionsPageActions.ActionType.LoadPage
),
[...]
));
One idea I had, was to create a custom action that only listens to navigations on the component with the dropdown, but i have no idea how to do this.
My current solution is following:
this.store.select(RouterSelectors.selectUrl).subscribe(() =>
this.store.dispatch(TransactionsPageActions.loadPage())
);
But this feels like it could cause some bugs in the future. Is there any way to achieve this in a clean way?
I read the documentation more closely and the effects guide tells you the following:
Note: Event streams are not limited to dispatched actions, but can be any observable that produces new actions, such as observables from the Angular Router, observables created from browser events, and other observable streams.
So I implemented a custom router action and dispatch it in an effect, that is called when the accountId in the router store changes.
accountIdChanged$ = createEffect(() => this.store.select(
RouterSelectors.selectRouteParam('accountId')
).pipe(
map((accountId) => RouterActions.accountIdChanged({accountId}))
));
Now I can listen to that action everywhere I want, for example in my transactions effect.
loadTransactions$ = createEffect(() => this.actions$.pipe(
ofType(RouterActions.ActionType.AccountIdChanged),
// [...]
));