如何处理用 observables 填充 select 选项的 http 代码错误
How to deal with http code errors filling select options with observables
我通过调用 Web 服务用可观察对象填充一些 select 选项。关键是我正在尝试获取 http 代码错误以隐藏表单(如果其中任何一个 http 代码与 200 不同)并向用户显示消息。
有人可以建议我这样做的好方法吗?
提前致谢!
回购:https://github.com/jreategui07/testing-subscriptions-form
模拟服务器运行:mockserver -p 8080 -m mock
GET.mock
HTTP/1.1 400 Bad Request
Access-Control-Allow-Origin: *
Content-Type: text/plain; charset=utf-8
Connection: keep-alive
[
{ "error": "c1", "error_des": "any error" }
]
为了将来参考,请尝试在此处粘贴相关代码,以便其他用户可以看到您正在尝试做什么。您的相关代码是您的 catalogue.service.ts:
export class CatalogueService {
requestOptions: any;
constructor(public http: HttpClient) {
const headers = new HttpHeaders({
'Content-Type': 'text/plain; charset=utf-8'
});
this.requestOptions = { headers: headers, observe: 'response' };
}
getColors() {
return this.http.get('http://localhost:8080/getColors', this.requestOptions).pipe(map(response => response['body']));
}
getBrands() {
return this.http.get('http://localhost:8080/getBrands', this.requestOptions).pipe(map(response => response['body']));
}
getSizes() {
return this.http.get('http://localhost:8080/getSizes', this.requestOptions).pipe(map(response => response['body']));
}
getFruits() {
return this.http.get('http://localhost:8080/getFruits', this.requestOptions).pipe(map(response => response['body']));
}
}
特别是,由于您已经正确观察到 response
,您可以简单地检查响应类型:
this.http.get('http://localhost:8080/getColors', this.requestOptions)
.pipe(
map(response => !response.ok ?
throw new Error('Request error, reponse code: ' + response.status :
response['body'])
);
请注意,在 map
中抛出错误将导致可观察对象出错,因此您可以在调用请求的代码中处理它,如下所示:
this.service.getColors().pipe(
catchError((error) => /* do something with that error */
);
综上所述,您确实要求 最佳实践 处理此问题。在这种情况下,如果您想以类似的方式处理所有 Http 响应(比如将它们记录在某处,或者显示一个工具提示,通知用户请求失败等),我建议查看 Http Interceptors。拦截器使您能够针对从 module/the 应用程序中调用的所有响应创建模块范围甚至应用程序范围的行为。
您可以向所有 select 可观察对象添加错误处理程序。注意这里我只收集最后一个错误并隐藏表单所以如果有多个错误你可以使用数组到 formHasError 变量。
- 定义一个变量来跟踪表单错误:
formHasError: string[] = [];
- 创建错误函数来处理错误
import { catchError } from 'rxjs/operators';
errorFn = catchError(e => {
const err = e && e.error && e.error[0] && e.error[0].error_des;
if(err){
this.formHasError.push(err);
}
return [];
});
- 在您的组件中,select observables 被修改为
this.colorSC$ = catalogueService.getColors().pipe(this.errorFn);
this.brandSC$ = catalogueService.getBrands().pipe(this.errorFn);
this.sizeSC$ = catalogueService.getSizes().pipe(this.errorFn);
this.fruitSC$ = catalogueService.getFruits().pipe(this.errorFn);
- 在您的模板中添加 formHasError
<form (ngSubmit)="onSubmit()" [formGroup]="anyForm" *ngIf="!formHasError.length">
...
</form>
<div class="error" *ngIf="formHasError.length">
Form has some errors:
<p *ngFor="let err of formHasError">{{err}}</p>
</div>
我通过调用 Web 服务用可观察对象填充一些 select 选项。关键是我正在尝试获取 http 代码错误以隐藏表单(如果其中任何一个 http 代码与 200 不同)并向用户显示消息。
有人可以建议我这样做的好方法吗?
提前致谢!
回购:https://github.com/jreategui07/testing-subscriptions-form
模拟服务器运行:mockserver -p 8080 -m mock
GET.mock
HTTP/1.1 400 Bad Request
Access-Control-Allow-Origin: *
Content-Type: text/plain; charset=utf-8
Connection: keep-alive
[
{ "error": "c1", "error_des": "any error" }
]
为了将来参考,请尝试在此处粘贴相关代码,以便其他用户可以看到您正在尝试做什么。您的相关代码是您的 catalogue.service.ts:
export class CatalogueService {
requestOptions: any;
constructor(public http: HttpClient) {
const headers = new HttpHeaders({
'Content-Type': 'text/plain; charset=utf-8'
});
this.requestOptions = { headers: headers, observe: 'response' };
}
getColors() {
return this.http.get('http://localhost:8080/getColors', this.requestOptions).pipe(map(response => response['body']));
}
getBrands() {
return this.http.get('http://localhost:8080/getBrands', this.requestOptions).pipe(map(response => response['body']));
}
getSizes() {
return this.http.get('http://localhost:8080/getSizes', this.requestOptions).pipe(map(response => response['body']));
}
getFruits() {
return this.http.get('http://localhost:8080/getFruits', this.requestOptions).pipe(map(response => response['body']));
}
}
特别是,由于您已经正确观察到 response
,您可以简单地检查响应类型:
this.http.get('http://localhost:8080/getColors', this.requestOptions)
.pipe(
map(response => !response.ok ?
throw new Error('Request error, reponse code: ' + response.status :
response['body'])
);
请注意,在 map
中抛出错误将导致可观察对象出错,因此您可以在调用请求的代码中处理它,如下所示:
this.service.getColors().pipe(
catchError((error) => /* do something with that error */
);
综上所述,您确实要求 最佳实践 处理此问题。在这种情况下,如果您想以类似的方式处理所有 Http 响应(比如将它们记录在某处,或者显示一个工具提示,通知用户请求失败等),我建议查看 Http Interceptors。拦截器使您能够针对从 module/the 应用程序中调用的所有响应创建模块范围甚至应用程序范围的行为。
您可以向所有 select 可观察对象添加错误处理程序。注意这里我只收集最后一个错误并隐藏表单所以如果有多个错误你可以使用数组到 formHasError 变量。
- 定义一个变量来跟踪表单错误:
formHasError: string[] = [];
- 创建错误函数来处理错误
import { catchError } from 'rxjs/operators';
errorFn = catchError(e => {
const err = e && e.error && e.error[0] && e.error[0].error_des;
if(err){
this.formHasError.push(err);
}
return [];
});
- 在您的组件中,select observables 被修改为
this.colorSC$ = catalogueService.getColors().pipe(this.errorFn);
this.brandSC$ = catalogueService.getBrands().pipe(this.errorFn);
this.sizeSC$ = catalogueService.getSizes().pipe(this.errorFn);
this.fruitSC$ = catalogueService.getFruits().pipe(this.errorFn);
- 在您的模板中添加 formHasError
<form (ngSubmit)="onSubmit()" [formGroup]="anyForm" *ngIf="!formHasError.length">
...
</form>
<div class="error" *ngIf="formHasError.length">
Form has some errors:
<p *ngFor="let err of formHasError">{{err}}</p>
</div>