I'm relatively new to NgRx, I've been using it for only a few months, and there's this issue I've been struggling with for days, and never found anything useful in the documentation about this.
I'm using Angular 8 with NgRx 8 as well. This is my pretty simple, dummy code.
getItems action
export interface GetItems {
param: number;
}
export const getItems = createAction("[App] Get items", props<GetItems>());
getItems effect:
getItems$ = createEffect(
() =>
this.actions$.pipe(
ofType(AppActions.getItems),
tap((action) => console.log(action.param),
exhaustMap(action => this.appService.getItems()),
map((response: Item[]) => {
console.log(action.param);
return this.store.dispatch(
AppActions.getItemsComplete({ items: response })
);
})
),
{ dispatch: false }
);
Dispatching getItems action:
ngOnInit(): void {
const param: number = 99;
this.store.dispatch(getItems({ param }));
}
Is there a way to reach the action's param payload inside the exhaustMap operator? As you can see here, the second console.log will push an error about the missin action object. My goal is: send a request to the appService first (without the getItems action parameter though), then dispatch the getItemsComplete action WITH the getItems action parameter.
One approach would be this:
getItems$ = createEffect(
() =>
this.actions$.pipe(
ofType(AppActions.getItems),
tap((action) => console.log(action.param),
exhaustMap(action => forkJoin(of(action), this.appService.getItems())),
map(([action, response]) => {
console.log(action.param);
return this.store.dispatch(
AppActions.getItemsComplete({ items: response })
);
})
),
{ dispatch: false }
);
forkJoin will make sure that both observables complete, then it will delegate the response array further down the pipe. You can have N
observables passed to forkJoin
, but you'll get the array response once all complete.