ngrx efektinde switchMap'te hata nasıl atılır

Aug 19 2020

Ngrx8, rxjs6 ve angular 9 kullanıyorum

Giriş yaptıktan sonra başka bir servisi aramam gerekiyor. Bu hizmet hata attığında, onu işlemek için efektimin bir kısmını catchError parçası yapmak istiyorum, sorun, try catch'teki hatayı yakalıyorum ve günlüğü görüyorum, ancak catchErrortetiklenmiyor.

Basitleştirilmiş kod

    login$ = createEffect(() => { return this.actions$.pipe(

            ofType(AuthActions.login),
            switchMap((action) =>
                this.userService.login(action.userName, action.password)
                    .pipe(
                        switchMap((token) => {
                            return throwError(new Error('hello'));
                        }),
                        map((token) => AuthActions.loginSuccess()),
                        catchError((error) => {
                            console.error('error', error); // I don't see this in console

                            return of(AppError({ error }));
                        })),
            ),
            catchError((error) => {
                console.error('error 2', error);

                return of(AppError({ error }));
            }),
        );
    });

Benim gerçek kodum

    login$ = createEffect(() => { return this.actions$.pipe(

            ofType(AuthActions.login),
            switchMap((action) =>
                this.userService.login(action.userName, action.password)
                    .pipe(
                        switchMap(async (token) => {
                            try {
                                await this.matrixService.initClient(action.userName, action.password);

                                return of(token);
                            }
                            catch (error) {
                                console.log('catch error', error); // I see this in console

                                return throwError(error);
                            }
                        }),
                        map((token) => AuthActions.loginSuccess()),
                        catchError((error) => {
                            console.error('error', error); // I don't see this in console

                            return of(AppError({ error }));
                        })),
            ),
            catchError((error) => {
                console.error('error 2', error);

                return of(AppError({ error }));
            }),
        );
    });

konsol çıkışı

Yanıtlar

1 RafiHenig Aug 19 2020 at 04:23

Aksine kullanmaktan daha Async-Awaitbeklemek sözdizimi Promisetarafından döndürülen matrixService.initClient(nedeniyle geçerli bağlamda işe yaramaz hangi tamamlanmasını switchMapoperatör beklemeden asyncbir dönüştürülebilir gibi, bunun için beklemeden iade düşünün, fonksiyonlar) Observableiçin (sayesinde switchMapoperatör kabul etme Promise) this.userService.loginbeklenmekle sonuçlanır .

login$ = createEffect(() => this.actions$
  .pipe(
    ofType(AuthActions.login),
    switchMap(({ userName, password }) => this.userService.login(userName, password)
      .pipe(
        switchMap(() => this.matrixService.initClient(userName, password)),
        map((token) => AuthActions.loginSuccess()),
        catchError((error) => {
          console.error('error', error);
          return of(AppError({ error }));
        })
      )
    ),
    catchError((error) => {
      console.error('error 2', error);
      return of(AppError({ error }));
    })
  )
);
HamzaZaidi Aug 19 2020 at 22:01

yorumlara göre önceki cevapları biraz değiştireceğim

login$ = createEffect(() => this.actions$
  .pipe(
    ofType(AuthActions.login),
    switchMap(({ userName, password }) => this.userService.login(userName, password)
      .pipe(
        map((token) => AuthActions.loginSuccess())
        tap(() => this.matrixService.initClient(userName, password)),
      )
    ),
    catchError((error) => {
      console.error('error 2', error);
      return of(AppError({ error }));
    })
  )
);

Sırayı değiştiriyorum, sürekli ateş ediyorum AuthActions.loginSuccess()ve sonra this.matrixService.initClient(userName, password).

catchErroriki kez aranmasına gerek yoktur, servis çağrısından kaynaklanan herhangi bir hata en dıştaki catchErroroperatörde yakalanacaktır .