首页 文章

在服务中重构Angular 4 http调用并包含错误

提问于
浏览
2

我并不完全了解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) => {

      });

(.catch行不允许,签名不正确)

等待明显的答案:)

4 回答

  • 0

    您收到有关错误签名的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 . 例如 . :

    return Observable.of(null); // Or...
    return Observable.of(/* Create your own LicenseKeyAndUsageModel here */);
    

    Observable.of 中使用的值将被传递,从而使您的订户免于首先发生错误的事实 .

    再次,要使用 Observable.of ,您可能需要添加以下内容:

    import 'rxjs/add/observable/of';
    
  • 3

    如果我正确理解你的问题你可以做错误处理 .

    无论您调用何种方法,订阅时都会执行以下操作 .

    const myResponse = someHttpService.getLicenseAndModel().subscribe(result => {
      return result,
      return error,
      return complete});
    
  • -1

    使用 .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请求 .

    ReferencesHttpResponse docs: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

  • 0

    老实说,你可能只想改变你的设计 . 404错误通常并不意味着服务器没有找到数据,这意味着您未经授权访问给定的URL . 你为什么不简单地返回null?

    也许我不完全理解你的问题?

相关问题