I have an effect that is based on the routerNavigatedAction from @ngrx/router-store.
pickForm$ = createEffect(() =>
this.actions$.pipe(
ofType(routerNavigatedAction),
filter((navigation) => navigation.payload.routerState.url.startsWith('/requetes/faire-une-requete/')),
concatLatestFrom(() => this.store.select(selectIsFormSelected)),
filter(([navigation, isFormSelected]) => isFormSelected),
map(([navigation, isFormSelected]) => RequestsActions.loadForm({ formId: getAllRouteParameters(navigation.payload.routerState).get('id') }))
)
);
So when I navigate to a page, it checks if the id corresponds to a form by using concatLatestFrom
and the selectIsFormSelected
selector and if so, it triggers a loadForm
action.
The problem is that selectIsFormSelected
is based on data that is fetched by calling loadAllForms
action in the ngOnInit.
When I navigate normally in the site, everything works wonderfully because when I navigate, I already got the data from the backend.
But when I refresh the page, or simply navigate to it from another site, what happens is that the effect above is triggered before the component had time to fetch the required data which means that selectIsFormSelected
is always false.
How can I rearrange my effect so that it depends on getting back data from loadAllForms
?
If you want to kind of "wait" for another part of the store to have been loaded, you can use a small trick with switchMap
, essentially making the previous emission (our source action) to wait for the specific selected part of our state. I think this might satisfy your use case:
pickForm$ = createEffect(() =>
this.actions$.pipe(
ofType(routerNavigatedAction),
filter((navigation) =>
navigation.payload.routerState.url.startsWith('/requetes/faire-une-requete/')),
switchMap((navigation) => this.store.select(selectAllForms).pipe(
skipWhile(allForms => allForms !== null),
map(() => navigation),
)
concatLatestFrom(() => this.store.select(selectIsFormSelected)),
filter(([navigation, isFormSelected]) => isFormSelected),
map(([navigation, isFormSelected]) => RequestsActions.loadForm({ formId: getAllRouteParameters(navigation.payload.routerState).get('id') }))
),
);
This way, you will start listening to this effect only after the allForms
have been loaded