[英]Angular how to avoid that errors break valueChanges
在我的 angular 6 应用程序中,我遇到了一些 rxjs 操作符的问题。 我有一个搜索字段,当用户在该字段中输入时,我需要调用我的服务(服务执行 GET 请求),如果该服务没有任何错误(如 500),它就可以工作。
但是 500 错误的请求破坏了值更改的链,可能我没有从服务中返回正确的值...
这是组件中的搜索字段:
this.manufacturer.valueChanges
.pipe(
filter((value: string) => (value ? value.length > 2 : false)),
tap(() => (this.loadingAutocomplete = true)),
debounceTime(500),
switchMap(val => this.frameService.getItems(val, "manufacturerAutocomplete")),
tap(() => (this.loadingAutocomplete = false)),
catchError(err =>
return of([]))
)
.subscribe(
manufacturers => {
this.matchingManufacturers.next(manufacturers);
},
err => {
this.loadingAutocomplete = false;
this.matchingManufacturers.next([]);
}
);
这是服务:
getItems(value: string, endPoint: string) {
return this.http.get(
this.endPointUrlService.cutLinks(this.endPointUrlService.map.get("frames")) + "/search/" + endPoint
).pipe(
map((res: string[]) => {
if (res) {
return res;
} else {
return [];
}
})
);
}
第一次用户输入一些它有效的东西,如果我有一个错误,则不会再次调用 valueChanges。 我需要处理组件中的错误,而不是服务中的错误。
由您对 valueChanges 属性的 rxjs 语句产生的 observable 已完成,这就是它不再反应的原因。
重要提示:一个可观察到的错误,将完成,并且您无法改变该行为。
您需要做的是防止端点服务的错误向下流入 switchMap 语句,并进一步流入链中。 如果它流入链条,则该链条将完成。 为了防止错误向下流,您需要在 api 调用抛出错误时返回 empty()。
getItems(value: string, endPoint: string) {
return this.http.get(this.endPointUrlService.cutLinks(this.endPointUrlService.map.get("frames")) + "/search/" + endPoint).pipe(
map((res: string[]) => {
if (res) {
return res;
} else {
return [];
}
}),
catchError(err => {
// report error to user
console.log(err);
// Important: stop observable from emitting anything
return empty();
})
);
}
有关该主题的更多信息:http ://www.syntaxsuccess.com/viewarticle/error-handling-in-rxjs
更早地捕获错误 - 在服务层中,如下所示:
getItems(value: string, endPoint: string) {
return this.http.get(this.endPointUrlService.cutLinks(this.endPointUrlService.map.get("frames")) + "/search/" + endPoint).pipe(
map((res: string[]) => {
if (res) {
return res;
} else {
return [];
}
}),
catchError(err => return of([]))
);
}
可能这个方法解决了我的问题,这是组件,服务没有捕获任何东西:
this.manufacturer.valueChanges
.pipe(
filter((value: string) => (value ? value.length > 0 : false)),
tap(() => (this.loadingAutocomplete = true)),
debounceTime(500),
switchMap(val =>
this.frameService.getItems(val, "manufacturerAutocomplete").pipe(
catchError(err => {
handleError(err);
this.loadingAutocomplete = false;
return [];
})
)
),
tap(() => (this.loadingAutocomplete = false))
)
.subscribe(
manufacturers => {
this.matchingManufacturers.next(manufacturers);
},
err => {
this.loadingAutocomplete = false;
this.matchingManufacturers.next([]);
}
);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.