Saya mencoba menangkap kesalahan pada efek tindakan tertentu. Semuanya berfungsi dengan baik, baik saat panggilan berhasil atau gagal. Namun, saya pikir kodenya sangat bertele-tele, dan dapat ditingkatkan, khususnya:

  • Bagian catchError, saya mengembalikan empty() tetapi saya bieleve harus mengembalikan tindakan SavedReplyDeleteFailed. Saat melakukannya, seluruh efek rusak dan tidak dapat dikompilasi, tidak yakin apa praktik terbaik untuk menangani ini.
  • Saya terlalu mengandalkan tap dan dispatch daripada mengembalikan tindakan dari panggilan balik map/mergeMap. Ketika saya melakukannya, kompilasi efek juga rusak.

Bagaimana saya dapat menerapkan peningkatan di atas?

    deleteSavedReply = createEffect(() => this.actions$.pipe(
        ofType(SavedRepliesActions.SavedReplyDeleteRequested),
        mergeMap( action => {
            this.store.dispatch( SavedRepliesActions.DeleteLoading({ isLoading: true }) );
            return this.savedRepliesService.deleteSavedReply(action.id).pipe(
                tap(res => {
                    this.store.dispatch( SavedRepliesActions.SavedReplyDeleteSucess({ id: action.id }));
                    this.toastr.success( 'Saved Reply has been successfully deleted');
                }),
                catchError((error) => {
                    this.store.dispatch( SavedRepliesActions.SavedReplyDeleteFailed({message: error.message}) );
                    this.toastr.error( error.message, 'Something went wrong');
                    this.store.dispatch( SavedRepliesActions.DeleteLoading({ isLoading: false }) );
                    return empty();
                })
            );
        }),
        map(() => {
            return SavedRepliesActions.DeleteLoading({ isLoading: false });
        }),
    ));

0
Yehia A.Salam 29 Februari 2020, 03:11

1 menjawab

Jawaban Terbaik

Anda dapat memilih cara yang lebih reaktif (menggunakan RxJS powerful), jadi sederhanakan sedikit kode Anda dengan sesuatu seperti ini:

deleteSavedReply$ = createEffect(() => this.actions$.pipe(
  ofType(SavedRepliesActions.SavedReplyDeleteRequested),
  mergeMap(action => this.savedRepliesService.deleteSavedReply(action.id).pipe(
    switchMap(res => [
      SavedRepliesActions.SavedReplyDeleteSucess({ id: res.id }),
      UiActions.showToastrSuccess('Saved Reply has been successfully deleted')
    ]),
    catchError(error => of(
      SavedRepliesActions.SavedReplyDeleteFailed({ message: error.message }),
      UiActions.showToastrError(error.message, 'Something went wrong')
    ]))
  ))
))

Untuk melakukan ini, dalam pola pikir redux, Anda harus:

  • Buat 2 tindakan baru UiActions.showToastrSuccess dan UiActions.showToastrError untuk menampilkan pesan Toastr. Menampilkan pesan bisa menjadi target untuk suatu tindakan.

  • Gunakan reducer untuk tanda loading Anda. Ini adalah bagian dari status Anda, jadi sebaiknya ubah nilainya di dalam peredam sebagai ganti efeknya.

Sebagai contoh :

on(SavedRepliesActions.SavedReplyDeleteFailed, (state) => ({
  ...state,
  loading: false
})),

on(SavedRepliesActions.SavedReplyDeleteRequested, (state) => ({
  ...state,
  loading: true
})),

Pilihan lain

Perhatikan bahwa opsi lain (atau peningkatan...) dapat berupa mengirimkan tindakan Toastr, di dalam tindakan SavedReplyDeleteSucess. Sebagai contoh :

deleteSavedReply$ = createEffect(() => this.actions$.pipe(
  ofType(SavedRepliesActions.SavedReplyDeleteRequested),
  mergeMap(action => this.savedRepliesService.deleteSavedReply(action.id).pipe(
    map(res => SavedRepliesActions.SavedReplyDeleteSucess({ id: res.id }))
    catchError(error => of(SavedRepliesActions.SavedReplyDeleteFailed({ message: error.message })))
  ))
))

savedReplyDeleteSucess$ = createEffect(() => this.actions$.pipe(
  ofType(SavedRepliesActions.SavedReplyDeleteSucess),
  map(_ => UiActions.showToastrSuccess('Saved Reply has been successfully deleted'))
))

savedReplyDeleteFailed$ = createEffect(() => this.actions$.pipe(
  ofType(SavedRepliesActions.SavedReplyDeleteFailed),
  map(message => UiActions.showToastrError(error.message, 'Something went wrong'))
))

Keuntungannya di sini adalah Anda dapat membuat kode Anda berkembang, dengan menambahkan beberapa efek tambahan jika berhasil atau gagal. Misalnya:

savedReplyDeleteFailed$ = createEffect(() => this.actions$.pipe(
  ofType(SavedRepliesActions.SavedReplyDeleteFailed),
  switchMap(message => [
    UiActions.showToastrError(error.message, 'Something went wrong')),
    SystemActions.sendTraceError(error)
))

Semoga bisa membantu.

1
Thierry Falvo 29 Februari 2020, 08:58