Observableのエラー発生以降にnext()が機能しなくなる。
https://angular.io/docs/ts/latest/tutorial/toh-pt6.html
上記チュートリアルに従いObservableにてhttp処理を実装しています。
this.heroes = this.searchTerms
.debounceTime(300) // wait 300ms after each keystroke before considering the term
.distinctUntilChanged() // ignore if next search term is same as previous
.switchMap(term => term // switch to new observable each time the term changes
// return the http search observable
? this.heroSearchService.search(term)
// or the observable of empty heroes if there was no search term
: Observable.of<Hero[]>([]))
.catch(error => {
// TODO: add real error handling
console.log(error);
return Observable.of<Hero[]>([]);
});`
・・・
this.searchTerms.next(term);
しかしながらここで1回でもhttpエラーが発生すると(上記のcatchのルートに入ると)、
以降nextをコールしてもデータが流れていきません。
ユーザーにしばらく待ったのち再トライすることを促し、もう一度SubmitさせるようなUIにしたいのですが、
エラーをハンドル(onError()をコール)しつつ、エラー発生後もストリーミングを止めない方法はありますでしょうか?
追記:
こちらの記事を参考に
下記の様にerrorが発生し得る処理のcatchをswitchMap()の中に入れ子にすることによってエラーが発生してもnextに空配列が渡されるようにはなりました。
※SOenを見ると"flatMap()を使えば良い"とflatMap()に限定した記事をよく見ますが、
Observable内の輻輳制御の仕様次第かと思いますので、
用途に応じswitchMap/flatMap/mergeMapどれでも良い理解ですが誤りあればご指摘ください。
this.heroes = this.searchTerms
.debounceTime(300) // wait 300ms after each keystroke before considering the term
.distinctUntilChanged() // ignore if next search term is same as previous
.switchMap(term => term // switch to new observable each time the term changes
// return the http search observable
? this.heroSearchService.search(term)
.catch(error => {
// TODO: add real error handling
console.log(error);//ここには来る
return Observable.of<Hero[]>([]);
})
// or the observable of empty heroes if there was no search term
: Observable.of<Hero[]>([]));
//確認用コード
this.heroes.subscribe(res=>{
console.log("next");//エラー時もここには来る(Hero[]が返る)
return res;
},
err=>{
console.log("err");//ここに来ない
})
しかしながら目的動作は「subscribe.onError()をコールしてもらいつつ、エラー時に受付を止めたくない」となります。
前述した記事に関してもonError()はコールされておらず、入れ子にしたcatchがコールされるのみでした。
(Observableのストリーミングの一部をUtilクラスに内包しており、使用者側にObservableを返すような作りにしているので、ストリーミング内のエラーが発生し得る処理ひとつひとつのcatchを使用者側に課したくなく、あくまでsubscribeで結果を通知したいためです。)