Bagaimana untuk melemparkan kesalahan dari RxJS peta operator (sudut)

Aku ingin melempar kesalahan dari saya yang dapat diamati's peta operator yang didasarkan pada kondisi. Misalnya jika benar data API tidak diterima. Silahkan lihat kode berikut:

private userAuthenticate( email: string, password: string ) {
    return this.httpPost(`${this.baseApiUrl}/auth?format=json&provider=login`, {userName: email, password: password})
        .map( res => { 
            if ( res.bearerToken ) {
                return this.saveJwt(res.bearerToken); 
            } else {
                // THIS DOESN'T THROW ERROR --------------------
                return Observable.throw('Valid token not returned');
            }
        })
        .catch( err => Observable.throw(this.logError(err) )
        .finally( () => console.log("Authentication done.") );
}

Pada dasarnya seperti yang anda lihat dalam kode, jika respon (res objek) doesn't memiliki 'bearerToken' saya ingin membuang sebuah kesalahan. Sehingga di langganan saya itu masuk ke 2 parameter (handleError) yang disebutkan di bawah ini.

.subscribe(success, handleError)

Ada saran?

Mengomentari pertanyaan (10)
Larutan

Hanya melemparkan kesalahan dalam peta() operator. Semua callback di RxJS dibungkus dengan try-catch blok sehingga'akan tertangkap dan kemudian dikirim sebagai sebuah kesalahan pemberitahuan.

Ini berarti anda don't kembali apa-apa dan hanya membuang kesalahan:

map(res => { 
  if (res.bearerToken) {
    return this.saveJwt(res.bearerToken); 
  } else {
    throw new Error('Valid token not returned');
  }
})

The throwError() (mantan yang dapat Diamati.membuang() di RxJS 5) adalah aplikasi yang dapat Diamati yang hanya mengirimkan sebuah kesalahan pemberitahuan tapi peta() doesn't peduli apa yang anda kembali. Bahkan jika anda kembali bisa Diamati dari peta() it'akan disahkan sebagai next pemberitahuan.

Hal terakhir, anda mungkin don't perlu menggunakan .catchError() (mantan catch() di RxJS 5). Jika anda perlu untuk melakukan efek samping apapun ketika sebuah kesalahan terjadi itu's lebih baik menggunakan ketuk(null, err => console.log(err)) (mantan melakukan() di RxJS 5) misalnya.

Jan 2019: Diperbarui untuk RxJS 6

Komentar (7)

Jika anda merasa seperti lempar Kesalahan baru() tampaknya un-diamati-suka anda dapat menggunakan switchMap:

// RxJS 6+ syntax
this.httpPost.pipe(switchMap(res => { 
   if (res.bearerToken) {
      return of(this.saveJwt(res.bearerToken)); 
   } 
   else {
      return throwError('Valid token not returned');
   }
});

atau lebih singkat:

this.httpPost.pipe(switchMap(res => (res.bearerToken) ? 
                                    of(this.saveJwt(res.bearerToken)) : 
                                    throwError('Valid token not returned')
));

Perilaku akan sama, it's hanya sintaks yang berbeda.

Anda're-benar berkata 'switch' dari http diamati dalam pipa yang berbeda yang dapat diamati, yang baik hanya 'pembungkus' nilai output, atau baru 'kesalahan' yang dapat diamati.

Don't lupa untuk menempatkan dari atau'll mendapatkan beberapa membingungkan pesan kesalahan.

Juga keindahan 'switchMap' adalah bahwa anda dapat kembali baru 'jaringan' perintah jika anda ingin untuk apa pun logika perlu dilakukan dengan saveJwt.

Komentar (1)

Meskipun pertanyaan ini sudah dijawab, saya'd ingin berbagi saya sendiri pendekatan (meskipun hanya sedikit berbeda dari yang di atas).

Aku akan memutuskan apa yang dikembalikan terpisah dari pemetaan dan sebaliknya. I'm tidak yakin apa yang operator terbaik selama ini jadi saya'll menggunakan tap.

this.httpPost.pipe(
  tap(res => { 
    if (!res.bearerToken) {
      throw new Error('Valid token not returned');
    }
  }),
  map(res => this.saveJwt(res.bearerToken)),
);
Komentar (3)