我并不完全了解rxjs的内容,所以这可能只是我所知道的差距。
我想将一些我的http内容重构成一个服务。目前我有这个......
this.http.get<LicenseKeyAndUsageModel>('api/license').subscribe(data => {
this.licenseKeyAndUsage = data;
}, (error: HttpErrorResponse) => {
if (error.status !== 404) {
//omitted for brevity, essentially notifies of unknown error.
}
});
要澄清一下,如果返回404,则表示没有现有的许可证密钥,这很好,因为我的本地变量从未设置过,每个人都很高兴。
但是,现在我想把它重构成一个服务。我看到的大多数示例都显示返回'get'并让调用者订阅结果。
return this.http.get<LicenseKeyAndUsageModel>('api/license');
听起来不错。
我不明白的是如何在服务中包含错误,以便调用者获取值或null。因此,我可以简单地将结果再次分配给局部变量,并让数据绑定完成其余的工作。
我已经看到了类似的东西的一些例子,建议传递一个回调,映射到订阅CompletionObserver,但这对我来说不好闻。
我怀疑答案可能是使用map和catch,但是我不能使用带有catch的HttpErrorResponse,这看起来很羞耻......
return this.http.get<LicenseKeyAndUsageModel>('api/license')
.map(data => { return data; })
.catch((error: HttpErrorResponse) => {
});
(。不允许捕获行,签名错误)
等待明显的答案:)
答案 0 :(得分:3)
您收到有关错误签名的TypeScript错误的原因是因为catch
的实施需要返回新的Observable
。根据您所显示的内容,问题实际上是您的void
返回类型。
为了重新抛出错误,您可以使用Observable.throw
,例如:
return Observable.throw(err);
否则,当您想忽略错误时,您可以使用类似Observable.empty
的内容,例如:
return Observable.empty();
要使用Observable.empty
,您可能需要添加以下内容:
import 'rxjs/add/observable/empty';
如果您想在使用catch
时返回不同的内容,可以使用Observable.of
。 e.g:
return Observable.of(null); // Or...
return Observable.of(/* Create your own LicenseKeyAndUsageModel here */);
Observable.of
中使用的值将被传递,从而使您的订阅者免于首先发生错误的事实。
同样,要使用Observable.of
,您可能需要添加以下内容:
import 'rxjs/add/observable/of';
答案 1 :(得分:0)
如果我能正确理解你的问题你可以做错误处理。
无论您调用哪种方法,订阅时都会执行以下操作。
const myResponse = someHttpService.getLicenseAndModel().subscribe(result => {
return result,
return error,
return complete});
答案 2 :(得分:0)
使用.catch
是非常好的解决方案。您错过的是error
类型为any
。这就是打字稿抱怨签名错误的原因。
return this.http.get('api/license')
//.map(data => { return data; }) //this is not needed,
// you may transform JSON string to actual object here:
.map(response => response.json())
.catch((error: any) => {
// Be aware, that error may be something different than HttpResponse (for example instance of Error or even string).
// For example, if .json() above would fail, you will get instance of Error class (the one built in JS engine).
// You may cast error to desired class here.
if(error instanceof HttpResponse && (error as HttpResponse).status == 404) {
// Handle this error as you wish here.
}
return Observable.throw(error);
});
另请注意Http
服务返回冷Observable
。这意味着,在您订阅返回的observable之前,不会发出HTTP请求。
<强>参考强>:
HttpResponse
个文档:
https://angular.io/api/common/http/HttpResponse
添加.catch
运算符的方式:
https://github.com/ReactiveX/rxjs/blob/master/src/add/operator/catch.ts#L10
.catch
的实际定义:
https://github.com/ReactiveX/rxjs/blob/master/src/operator/catch.ts#L64
答案 3 :(得分:-1)
老实说,您可能只想改变您的设计。 404错误通常并不意味着服务器没有找到数据,这意味着您未经授权访问给定的URL。你为什么不简单地返回null?
也许我不完全理解你的问题?