【发布时间】:2019-11-14 11:57:26
【问题描述】:
最近我将我的 Ionic 3 项目升级到了 Ionic 4,通过这次升级还更新了其他几个包(Angular 5 --> 8 和 RxJs 5.5 --> 6.5)。代码中所需的大部分更改都进展顺利,但有一个更改我无法解决。
在我的一项服务中,我有一个执行 API 获取 (GET) 的函数。提取 (http GET) 中的任何错误都在全局错误函数中处理。在我的旧 Ionic 3 / RxJs 5~ 应用程序中,这是按如下方式完成的:
public fetch(): Observable<T[]> {
let _path: string = this.path;
const url = this.getUrl(_path);
return this.http
.get(url, this.options)
.catch(this.handleError);
}
handleError 函数在另一个服务中定义:
protected handleError(error: any) {
const errMsg = (error.message) ? error.message :
error.status ? `${error.status} - ${error.statusText}` : 'Server error';
this.logger.error('API endpoint: ' + this.path, errMsg);
this.showErrorToast(); // not async in Ionic 3
return Observable.throw(errMsg);
}
在我的 Ionic 4 / RxJs 6 应用程序中,我试图重新创建它但没有成功。 我已阅读并更改以下内容:
-
catch已弃用,应替换为catchError -
Observable.throw也已弃用,应替换为throwError
所以我的新实现如下所示:
public fetch(): Observable<T[]> {
let _path: string = this.path;
const url = this.getUrl(_path);
return this.http
.get(url, this.options)
.pipe(
catchError(() => { // this line is returning a error
this.handleError;
}
));
}
protected handleError(error: any) {
const errMsg = (error.message) ? error.message :
error.status ? `${error.status} - ${error.statusText}` : 'Server error';
this.logger.error('API endpoint: ' + this.path, errMsg);
this.showErrorToast(); // now async in Ionic 4
return throwError(errMsg); // Changed this
}
但是,catchError(() => 返回以下错误:
Argument of type '() => void' is not assignable to parameter of type '(err: any, caught: Observable<Object>) => ObservableInput<any>'.
Type 'void' is not assignable to type 'ObservableInput<any>'
在尝试了其他几件事后,我有点不知道如何解决这个问题,有什么想法或建议吗?
更新
在实施了一些建议的解决方案后,我一直得到与前一个相同但不同的错误:
Type 'Observable<Object>' is not assignable to type 'Observable<T[]>'.
The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead?
Type 'Object' is missing the following properties from type 'T[]': length, pop, push, concat, and 26 more
所以经过一番调查,我想出了这个(使用@theMayer提出的解决方案):
我变了:
return this.http
.get(url, this.options)
.pipe(
catchError(e => {
this.handleError(e);
return EMPTY;
}
));
到:
return this.http
.get<T[]>(url, this.options)
.pipe(
catchError(e => {
this.handleError(e);
return EMPTY;
}
));
以上更改消除了错误,但我不确定这是要走的路吗? fetch 函数将遍历定义 API 端点的多个其他服务。
【问题讨论】:
-
使用
catchError(this.handleError) -
@fridoo - 它可以在语法上工作,但是当直接引用一个函数时,
this在运行时变得不受约束(除非他们已经在更高版本的 typescript/javascript 中修复了这个问题)。 -
@theMayer 是的,但是正如 OP 之前使用的
catch(this.handleError)(我认为一切正常)切换到catchError(this.handleError)应该完全一样。如果要保留当前上下文,可以使用catchError(this.handleError.bind(this)) -
或者你可以写
catchError(e => this.handleError(e))-> 但它需要在下面更改方法签名。 -
好的,所以你有一个不同的问题 - 你似乎不明白所涉及的类型。你有一个称职的IDE吗?我推荐安装了 Angular 语言服务的 Visual Studio 代码。
标签: angular ionic-framework rxjs