Как отправить несколько действий из отдельных эффектов в NgRx? - PullRequest
1 голос
/ 31 марта 2020

Мой текущий код эффекта такой, вот мой код эффекта, в котором в данный момент я отправляю одно действие из эффекта. Но я хочу отправить еще одно действие уведомлениеNew (), которое я прокомментировал ниже в коде эффекта.

    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.

Так как этого добиться?

Ответы [ 2 ]

4 голосов
/ 31 марта 2020

Вы можете использовать switchMap вместо оператора map, чтобы иметь возможность вернуть array действий, которые затем будут генерировать каждое действие:

... 
this.ReservationReqService.sendReservationRequest(action.reservationRequest).pipe(
  switchMap(response => {
    if (response.status) {
      this.helperService.snackbar('Request Sent.');
      return [
        ReservationReqActions.bookPropertyRequestSuccess({ reservationRequest: response.result }),
        UiActions.notificationNew({...})
      ]
...

Предложение

Вот предложение по рефакторингу с меньшим количеством кода:

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);
        ])
      )
    );
  ));

Для этого вам нужно вернуть ответ "classi c" с HttpClient внутри вашего sendReservationRequest метода:

sendReservationRequest(request: ReservationRequest) {
  return this.httpClient.post(SERVICE_URL);
  // no {observe: 'response'} here
}

Примечание : Очень просто в этом примере, но, возможно, в некоторых ситуациях может потребоваться проверить содержимое errorResponse внутри catchError. Чтобы избежать проблем с errorResponse.error.message ... Out of topi c здесь.

0 голосов
/ 31 марта 2020

Я решаю такого рода проблемы с другим эффектом, где я фильтрую для успеха Действие:

    notificationNew$ = createEffect(() => {
      return this.actions$.pipe(
        ofType(ReservationReqActions.bookPropertyRequestSuccess),
        map((action)=> ReservationReqActions.notificationNew(action.payload) )

Так что это ясно структурировано, и код не слишком сложен.

...