私はHttpInterceptor
AngularのAPIを使用していますがHttpClientModule
、現在は状況に悩まされています。これが私のユースケースです。
私のアプリケーションでは、サービスがhttp呼び出しを行う場合、その前に別のサイレントhttp呼び出しを行い、その結果をローカルに保存したいと思います。サイレントコールが完了すると、私だけがサービスのhttpコールを続行し、その結果を返します。
これが私がしていることです。(HttpInterceptorを使用)
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (req.url.match(/api\//)) { // api call
http.post('/auth/silentCall', {user: 123}).subscribe(
(data) => {
console.log(data);
const clone = req.clone({ setHeaders: { 'Authorization ': tokenService.getToken() } });
return next.handle(clone).do((event: HttpEvent<any>) => {
if (event instanceof HttpResponse) {
console.log('Service's call response');
}
}, (err: any) => {
if (err instanceof HttpErrorResponse) {
console.log('Network call err', err);
}
});
},
(err) => {
if (err instanceof HttpErrorResponse) {
return Observable.throw(err);
}
);
} else {
console.log('Not an api call..It's an auth call');
return next.handle(req); // call original auth request.
}
}
さて、上記のコードの問題は、内部サイレント呼び出しを正常に実行しているが、その後は元のapi呼び出しを呼び出さないことです。そのため、サービスは永遠に待機し続けます。
更新:動作するプランカーを追加しました。https://plnkr.co/edit/WFecj8fFZ6z4G6mpLSCr?p=preview
呼び出しが行われる順序と、ブラウザーの開発ツールを使用して追加されるヘッダーに注意してください。
また、以下のソリューションでは、標準の演算子の代わりにRxJSのlettable演算子を使用していることに注意してください(これは、異なる動作をするべきではありません...コードがコンパイルされない場合にこのメモを追加します)
問題の原因はintercept
、呼び出しが一致した場合にメソッドがハンドルを返さないという事実です/api
。
コードを次のようなものに更新します
intercept(req: HttpRequest<any>, next: HttpHandler):Observable<HttpEvent<any>> {
if (req.url.match(/api\//)) { // api call
return http.post('/auth/silentCall', {user: 123}).pipe(switchMap((response) => {
console.log('Service's call response');
let clone = req.clone({ setHeaders: { 'Authorization ': tokenService.getToken() } });
return next.handle(clone);
}), catchError((err) => {
if(err instanceof HttpErrorResponse) {
console.log('Your logging here...');
let clone = req.clone({ setHeaders: { 'Authorization ': tokenService.getToken() } });
return next.handle(clone);
}
return Observable.throw(err);
}));
} else {
return next.handle(req); // call original auth request.
}
}
の応答は、メソッドhttp.post
によって返された監視可能なシーケンスを返すため、next.handle()
またはで終了した監視可能なものをスローするためにフラットマップされていることに注意してくださいObservable.throw()
。
また、api呼び出しが失敗した場合、catchブロック(またはサブスクライブの場合はエラーハンドラー関数)が呼び出されるため、if条件が削除されていることにも注意してください。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加