类型'void'不能分配给'ObservableInput <{}>'类型

ees*_*ein 43 typescript angular4

迁移到TS 2.2.2后,这个错误开始弹出,所以我假设这是问题......代码没有停止工作,但现在我收到了这个错误,我尝试了一些事情,比如返回一个空的observable捕获重新抛出的异常并返回一个对象,似乎没有任何工作.为什么现在发生这种情况?它不应该理解我重新抛出异常而不期待回归吗?我误读了这个错误吗?

这是完整的错误描述:

在此输入图像描述

这是完整的代码:

return request
    .map((res: Response) => res.json())
    .catch((error: any) => {
        // todo: log?

        if (error.status == 500) {
            this.alertService.showError(error.statusText);
        } else if (error.status == 588) {
            this.alertService.showAlert(error.statusText);
        }

        Observable.throw(error.statusText);
    });
Run Code Online (Sandbox Code Playgroud)

我尝试返回Observable,但我的包装器方法需要返回类型T,这是我的反序列化请求(map(...))的返回.如果我确实返回,throw这是我得到的错误:

[ts]类型'Observable'不能赋值为'T'

我正在使用:

  • Angular4
  • 打字稿2.2.2

Bou*_*ine 62

你必须返回Observable

 return request
    .map((res: Response) => res.json())
    .catch((error: any) => {
        // todo: log?

        if (error.status == 500) {
            this.alertService.showError(error.statusText);
        } else if (error.status == 588) {
            this.alertService.showAlert(error.statusText);
        }

        return Observable.throw(error.statusText);
    });
Run Code Online (Sandbox Code Playgroud)

  • 我收到“类型‘typeof Observable’上不存在属性‘throwError’”。ts(2339)` (RxJS 7.4)。与“扔”相同。 (4认同)
  • Bougarfaoui,我将其标记为答案,因为我现在能够找出问题所在 :) 在您的回答之后,我决定更仔细地查看代码,我确实应该返回它(即使这个概念仍然有点对我来说有点奇怪,因为它被重新抛出),但问题是我的包装方法的预期回报。一旦我将其更改为期望 Observable&lt;T&gt; 就可以了。谢谢你。 (2认同)

Fad*_*kar 9

 return Observable.throw(error);
Run Code Online (Sandbox Code Playgroud)

可观察到的。不推荐使用 throw 在拦截器中使用像这样的 throwError 运算符

intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
   return next.handle(request).pipe(
    catchError(err => {
      if (err.status === 401) {
       // remove Bearer token and redirect to login page
        this.router.navigate(['/auth/login']);
      }
      return throwError( err );
    }));
}
Run Code Online (Sandbox Code Playgroud)


Pra*_*sar 7

有时当你不使用箭头功能调用catch时,如下所示

getUserList() {
    return this.http.get(this.constURL + '/api/url/here', this.headerOptions)
    .catch(this.handleError);
}

handleError(error: Response) {
    if (error.status == 500) {      
      this.router.navigate(['/login']);
    } else {
      return Observable.throw(error);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后它给出了错误

错误TypeError:无法读取未定义的属性'navigate'

因为在handleError函数中这个对象是不可访问的..如果你控制this.router然后你将得到未定义..所以这个对象不工作,并没有得到路由器所有可用的方法

所以你必须在这里使用箭头功能,如下所示

getUserList() {
    return this.http.get(this.constURL + '/api/url/here', this.headerOptions)
    .catch(error => { 
      return this.handleError(error);
    });
}

handleError(error: Response) {
    if (error.status == 500) {      
      this.router.navigate(['/login']);
    } else {
      return Observable.throw(error);
    }
}
Run Code Online (Sandbox Code Playgroud)

另外如果你没有提到returnError函数的返回,那么它会再次抛出错误

类型'(错误:任何)=> void'的参数不能分配给类型的参数

因此必须为handlerError函数键入return.

详细检查这里.他已经很好地解释了所有可能的错误和解决方案.工作对我来说


Jos*_*ndo 5

这是RXJS 6对angular 6的回答。在您的请求函数中,它看起来与此类似。请注意,catch已被catchError和替换Observable.throw为现在throwError。同样在RXJS 6中,我们使用管道将我们希望执行的一系列功能结合在一起,而不是之前的点链。

//In your service

getData(url: string): Observable<any> {
    let options = this.getHTTPOptions();
    return this.http.get<any>(url, options).pipe(
          catchError( (err: any, caught: Observable<any>) => { return 
        throwError(this.generalErrorHandler(err, caught)) } ) );
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以有一个错误处理程序。关键是要returncatchError上述两个函数中均指定关键字,并在处理程序中返回错误。箭头(=>)使您可以将调用函数的上下文传递给错误处理程序,这意味着您可以做一些很酷的事情,例如this.router.navigate(['someroute']);(如果您在服务中导入了路由器)

//In your service

  generalErrorHandler(error: any, caught: Observable<any>): Observable<any> {
    console.log('error caught: ', error);
    if( error.error.status == "INVALID_TOKEN" || error.error.status == "MAX_TOKEN_ISSUE_REACHED"){
      console.log('token has expired');
      this.logout();
      return error;
    }
    return error;
  }
Run Code Online (Sandbox Code Playgroud)

一些关键的导入才能使它起作用:

//Imports for the service

import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
import { Http, Response } from '@angular/http';
import { catchError, map } from 'rxjs/operators';
import { Observable, throwError, of} from 'rxjs';
Run Code Online (Sandbox Code Playgroud)

最后,订阅请求以获取数据:

//In your component, don't forget to import your service

let response$ = this.someService.getData('url here');
response$.subscribe( 
    data => { console.log('do stuff to data here', data); },
    err => { console.log("couldn't get data, maybe show error to user"); },
    () => { console.log('function that is called upon finish'); }
);
Run Code Online (Sandbox Code Playgroud)