Reputation: 758
My current effect code is like that here is my effect code in which currently i am dispatching single action from effect. But i want to dispatch one more action notificationNew() which i have commented in below effect code.
bookPropertyRequest$ = createEffect(() => {
return this.actions$.pipe(
ofType(ReservationReqActions.bookPropertyRequest),
concatMap(action =>
this.ReservationReqService.sendReservationRequest(action.reservationRequest).pipe(
map(response => {
if (response.status) {
this.helperService.snackbar('Request Sent.');
// Here i want to dispatch another action - notificationNew()
return ReservationReqActions.bookPropertyRequestSuccess({ reservationRequest: response.result });
} else {
const errorCode = response.errorCode;
if (errorCode !== null) {
this.helperService.errorAlert('', response.message, 'error');
return ReservationReqActions.bookPropertyRequestFailure({
error: {
type: response.errorCode || null,
message: response.message
}
});
}
}
}),
catchError(error => EMPTY)
)
)
);
});
Now I want to dispatch another action from action notificationNew() when the above-mentioned effect is success. So my my concern is how we can dispatch multiple actions from single effect.
So how to achieve this?
Upvotes: 3
Views: 3423
Reputation: 6300
You can use switchMap
in place of map
operator, to be able to return an array
of actions, which will then emit each action :
...
this.ReservationReqService.sendReservationRequest(action.reservationRequest).pipe(
switchMap(response => {
if (response.status) {
this.helperService.snackbar('Request Sent.');
return [
ReservationReqActions.bookPropertyRequestSuccess({ reservationRequest: response.result }),
UiActions.notificationNew({...})
]
...
Here is a proposition of refactoring with less code :
bookPropertyRequest$ = createEffect(() => this.actions$.pipe(
ofType(ReservationReqActions.bookPropertyRequest),
concatMap(action =>
this.reservationReqService.sendReservationRequest(action.reservationRequest).pipe(
switchMap(response => [
ReservationReqActions.bookPropertyRequestSuccess({ reservationRequest: response.result }),
UiActions.notificationNew({...})
]),
catchError(errorResponse => [
ReservationReqActions.bookPropertyRequestFailure({
error: errorResponse.error
}),
UiActions.errorAlert(errorResponse.error.message);
])
)
);
));
To do that, you need to return the "classic" response with HttpClient
inside your sendReservationRequest
method:
sendReservationRequest(request: ReservationRequest) {
return this.httpClient.post(SERVICE_URL);
// no {observe: 'response'} here
}
Note: Very simple in this example, but maybe in some situation it could be necessary to test errorResponse
content inside catchError
. To avoid any issue with errorResponse.error.message
... Out of topic here.
Upvotes: 6
Reputation: 220
I solve this kind of problems with an other effect, where i filter for the success Action:
notificationNew$ = createEffect(() => {
return this.actions$.pipe(
ofType(ReservationReqActions.bookPropertyRequestSuccess),
map((action)=> ReservationReqActions.notificationNew(action.payload) )
So it is clear structured and the code is not too complicated.
Upvotes: 0