Angular 2とRxJSを使用して、APIレイヤーからデータを取得しています。HTTPリクエストを処理するために作成した基本サービスがあります。次のコードは私のサービス内でこれを行います:
protected apiGet(uri: string): Observable<HttpMappedResponse<T>> {
return this.mapAndHandle<T>(this.http.get(uri));
}
private mapAndHandle<T>(observable: Observable<Response>): Observable<HttpMappedResponse<T>> {
const o = observable
.map(res => {
const data = res.json() || {};
const mappedResponse = new HttpMappedResponse<T>(res, data);
// Retrieve page information from HTTP headers
mappedResponse.pageInfo = new PageInfo(res.headers);
return mappedResponse;
})
.share();
o.subscribe(null, e => this.errorService.handleHttpResponse(e));
return o;
}
これはうまく機能し、電話をかけるときに必要なすべてのデータを取得しますapiGet()
。私が今やろうとしていることは次のとおりです。
.catch()、. retryWhen()、. map()、および.flatMapTo()を使用しようとしましたが、成功しませんでした。最も近いのは次のとおりです。
enum HttpVerb {
Put,
Post,
Get,
Delete
}
private mapAndHandle<T>(uri: string, type: HttpVerb): Observable<HttpMappedResponse<T>> {
const restObservable = this.getRestObservable(uri, type);
const o = restObservable
.map(res => this.mapToHttpMappedResponse<T>(res))
.catch((error, sourceObservable) => {
const data = error.json() || {};
if (error.status === 401 && data.Message === 'Token expired') {
console.log('Retrying');
// Refresh the expired auth token
const refreshToken = this.authService.userData.RefreshToken;
console.log(refreshToken);
this.authService
.refresh(new RefreshRequestModel(refreshToken))
.subscribe(x => null);
// Retry original
return this
.getRestObservable(uri, type)
.map(x => this.mapToHttpMappedResponse(x));
}
throw error;
})
.share();
o.subscribe(null, e => {
this.errorService.handleHttpResponse(e);
});
return o;
}
private mapToHttpMappedResponse<T>(res: Response): HttpMappedResponse<T> {
console.log('Attempt ' + Date.now());
const data = res.json() || {};
const mappedResponse = new HttpMappedResponse<T>(res, data);
// Retrieve page information from HTTP headers
mappedResponse.pageInfo = new PageInfo(res.headers);
return mappedResponse;
}
しかし、これは私に正しい結果を与えません。
これを行うために使用できる演算子はありますか?tryWhen()が最も論理的であるように見えますが、私はRxJで混乱し続けています!
あなたが抱えている問題の1つは、通話を連鎖させていないことです。更新呼び出しは再試行呼び出しにチェーンされている必要flatMap
があり、同じ監視可能なストリームに保持するために、または同様のものを活用する必要があります。
この質問に対する私の答えを見てください。
これがあなたがそれを達成する方法です:
catch
RxJSから演算子を追加する必要があります。これはエラーが発生する場所であり、それに応じて処理できます。
更新ロジックがインターセプターを通過するようにするには、呼び出しを返す必要があり、関数もを返す必要がありObservable
ます。たとえば、上記の元のロジックを変更します。
this.http.request(url, options)
.map((res: Response) => res.json())
.catch((error: any) => {
const err = error.json();
// Refresh JWT
if (err.status === 401) {
// refreshToken makes another HTTP call and returns an Observable.
return this.refreshToken(...);
}
return Observable.throw(err);
});
元のリクエストを再試行できるようにする場合は、元のリクエストデータを渡して、トークンが正常に更新されたときに再度呼び出しを行えるようにすることができます。たとえば、これはrefreshToken
関数がどのように見えるかです。
refreshToken(url: string, options: RequestOptionsArgs, body: any, tokenData: any): Observable<any>
return this.post(`${this.url}/token/refresh`, tokenData)
.flatMap((res: any) => {
// May want to use response data to set new tokens in your local storage or whatever here...
// This is where I retry the original request
return this.request(url, options, body);
});
}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加