[英]NestJS HttpService All Method API Call is not working when Interceptor is used
NestJS API App 使用 HttpService 調用另一個 API 並且它在沒有使用自定義攔截器時工作。 HttpService API 調用已執行,但未到達另一個 API 並且看不到響應。
這是獲取呼叫代碼
get(path: string, body: any = {}): Observable<AxiosResponse<any>> {
console.log('DomainAPI Response Begining');
const url = this.baseURL + path;
this.updateLastUtilizedTimestamp();
return this.httpService.get(url, { validateStatus: null }).pipe(
tap(data => {
console.log('DomainAPI Response Tap', data);
}),
retryWhen(
this.rxJSUtilsService.genericRetryStrategy({
numberOfAttempts: 3,
delayTime: 200,
ignoredErrorCodes: [500],
}),
),
catchError(this.formatErrors),
);
}
如果使用任何自定義攔截器,我在調試時發現以下內容。
arguments:TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
Postman 顯示以下響應。
{
"statusCode": 500,
"message": {
"Title": "TypeError",
"Type": "Error",
"Detail": "Converting circular structure to JSON\n --> starting at object with constructor 'Observable'\n | property 'operator' -> object with constructor 'CatchOperator'\n --- property 'caught' closes the circle",
"Status": "Status",
"Extension": ""
},
"timestamp": "Exception - AllExceptionsFilter 2019-12-26T17:29:42.447Z"
}
我將上面的內容更改如下,但仍然無法正常工作
get(path: string, body: any = {}) {
console.log('DomainAPI Response Begining');
const url = this.baseURL + path;
this.updateLastUtilizedTimestamp();
return this.httpService.get(url, { validateStatus: null }).pipe(
map(response => {
console.log('DomainAPI Response Tap', response.data);
return response.data;
}),
);
}
它在 postman 中給出以下響應
{
"data": {
"_isScalar": false,
"source": {
"_isScalar": false,
"source": {
"_isScalar": false
},
"operator": {}
},
"operator": {}
}
}
請指教
async get(path: string, body: any = {}): Promise<any> {
...
const res = await this.httpService.get(url, { validateStatus: null }).toPromise();
return res.data;
}
get(path: string, body: any = {}) {
...
return this.httpService.get(url, { validateStatus: null })
.toPromise()
.then(res => res.data)
.catch(err => this.logger.error(err));
}
使用 .toPromise() 方法轉換為 promise 已被棄用,因為我們正在使用可觀察對象,並且 promise 僅返回一個值,而可觀察對象可能不返回任何值或返回多個值(參見更多@:轉換為承諾)。 因此,作為使用上述問題的示例,解決方案將是:
import { lastValueFrom } from 'rxjs';
get(path: string, body: any = {}): Observable<AxiosResponse<any>> {
console.log('DomainAPI Response Begining');
const url = this.baseURL + path;
this.updateLastUtilizedTimestamp();
return await lastValueFrom(
this.httpService.get(url, { validateStatus: null })
.pipe(
tap(data => {
console.log('DomainAPI Response Tap', data);
}),
retryWhen(
this.rxJSUtilsService.genericRetryStrategy({
numberOfAttempts: 3,
delayTime: 200,
ignoredErrorCodes: [500],
}),
),
catchError(this.formatErrors),
));
}
基本上你所要做的就是用 firstValueFrom 或 lastValueFrom 包裝整個 http 請求,在這種情況下 lastValueFrom 是合適的。 請訪問 rxjs 上面關於轉換為承諾的文檔的鏈接,以了解更多信息。
注意:我只添加了 lastValueFrom 導入,只是作為所需內容的明確指示。
這是使用我自己的代碼的另一個示例:
async send_otp(
phone: string,
channel: string,
): Promise<Observable<AxiosResponse<any>>> {
return await lastValueFrom(
this.httpService
.post(`/messaging/otp/`, {
sender: 'Oyinkayy',
destination: '234' + String(phone).slice(1),
length: 6,
channel: channel,
reference: '',
})
.pipe(
tap((resp) => console.log(resp)),
map((resp) => {
return resp.data;
}),
tap((data) => console.log(data)),
catchError(async (err) => {
return err;
}),
),
);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.