[英]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.