NgRx - получить подтверждение ошибки из бэкэнда и передать компоненту - PullRequest
0 голосов
/ 22 февраля 2019

Я пытаюсь получить сообщения об ошибках из API и показать внутри входных данных моей формы, чтобы пользователь мог видеть, что не так с отправляемыми данными.

Ответ от API:

{
  "message": "The given data was invalid.",
  "errors": {
    "name": [
      "This name is already in use."
    ]
  }
}

user-form.component.ts

this.store.dispatch(new actions.CreateUser(user));

user.effect.ts

@Effect()
  CreateUser$: Observable<Action> = this.actions$.pipe(
    ofType(UserActions.CREATE_USER),
    map((action: UserActions.CreateUser) => action.payload),
    switchMap(payload => {
      return this.userService.save(payload).pipe(
        map((user: User) => {
          return new UserActions.CreateUserSuccess(user);
        }),
        catchError(err => {
          return of(new UserActions.CreateUserFail());
        })
      );
    })
  );

Как получить эту ошибку и передать ее обратно моему компоненту?

Должен ли я делать подобное внутри эффектов и подписывать его на Действия, ожидающие ошибки CreateUserFail?Я не уверен, что это хорошая практика, так как он будет слушать все виды действий.

Ответы [ 2 ]

0 голосов
/ 22 февраля 2019

Мы создали селектор и подписались на него.

Эффект

  @Effect()
  createProduct$: Observable<Action> = this.actions$.pipe(
    ofType(productActions.ProductActionTypes.CreateProduct),
    map((action: productActions.CreateProduct) => action.payload),
    mergeMap((product: Product) =>
      this.productService.createProduct(product).pipe(
        map(newProduct => (new productActions.CreateProductSuccess(newProduct))),
        catchError(err => of(new productActions.CreateProductFail(err)))
      )
    )
  );

Редуктор

case ProductActionTypes.CreateProductFail:
  return {
    ...state,
    error: action.payload
  };

Селектор

export const getError = createSelector(
  getProductFeatureState,
  state => state.error
);

Компонент

// Watch for changes to the error message
this.errorMessage$ = this.store.pipe(select(fromProduct.getError));

Шаблон

<div *ngIf="errorMessage$ | async as errorMessage" class="alert alert-danger">
  Error: {{ errorMessage }}
</div>

Выполный пример можно найти здесь: https://github.com/DeborahK/Angular-NgRx-GettingStarted/tree/master/APM-Demo4

0 голосов
/ 22 февраля 2019

Этого должно быть достаточно, чтобы изменить catchError следующим образом:

catchError(err => {
  return new UserActions.CreateUserFail(err);
})

также рассмотрите возможность использования неявного возврата:

map( (user: User) => new UserActions.CreateUserSuccess(user) ),
catchError( err => new UserActions.CreateUserFail(err) )

...