简体   繁体   English

我如何使用 catchError() 并仍然返回带有 rxJs 6.0 的类型化 Observable?

[英]How do I use catchError() and still return a typed Observable with rxJs 6.0?

cdSo I'm trying to migrate some of my Angular 5 code to 6, and I understand most of the changes required for rxjs to work using the.pipe() operator. cdSo 我正在尝试将我的一些 Angular 5 代码迁移到 6,并且我了解 rxjs 使用 .pipe() 运算符工作所需的大部分更改。 It works as you would expect for 'pipable' operations.它的工作方式与您对“可管道”操作的预期一样。

However, the behavior of catchError() is different than the .catch() operator.但是, catchError()的行为不同于.catch()运算符。 Prior to rxjs 6 I used the .catch() operator to transform the error input into aa consistent error object that can then be caught in the `.subscribe().在 rxjs 之前 6 我使用.catch()运算符将错误输入转换为一个一致的错误 object 然后可以在 .subscribe() 中捕获。

getAlbums(): Observable<Album[]> {
     return this.httpClient.get<Album[]>(this.config.urls.url("albums"))
           .map(albumList => this.albumList = albumList)
           .catch(new ErrorInfo().parseObservableResponseError);            
    }

new ErrorInfo().parseObservableResponseError is a function that takes a error object as input and parses the input error into a simpler error object with a normalized object. Catch returns Observable<any> : new ErrorInfo().parseObservableResponseError是一个 function,它将错误 object 作为输入,并将输入错误解析为更简单的错误 object,并归一化为 object。Catch 返回Observable<any>

parseObservableResponseError(response): Observable<any> {
    let err = new ErrorInfo();
    ...
    return Observable.throw(err);        
}

This worked great for easily handling errors up rxjs5 - errors basically are captured as part of the pipeline and then throw a well known error structure that can be captured .subscribe() error function.这对于轻松处理 rxjs5 上的错误非常有用——错误基本上作为管道的一部分被捕获,然后抛出一个众所周知的错误结构,可以捕获.subscribe()错误 function。

Moving that same code to rxjs 6 however and using .pipe() I am trying to do the following:然而,将相同的代码移动到 rxjs 6 并使用.pipe()我正在尝试执行以下操作:

getAlbums(): Observable<Album[]> {
    return this.httpClient.get<Album[]>(this.config.urls.url("albums"))
                .pipe(
                    map(albumList => this.albumList = albumList),
                    catchError(new ErrorInfo().parseObservableResponseError)                        
                );           
}

However this doesn't work because catchError now returns a result of Observable<any> into the pipeline, which is not what I want here.然而,这不起作用,因为 catchError 现在将Observable<any>的结果返回到管道中,这不是我想要的。 In essence I just want to re-throw any errors as I did before.本质上,我只想像以前一样重新抛出任何错误。

error TS2322: Type 'Observable<{} |错误 TS2322:类型 'Observable<{} | Album[]>' is not assignable to type 'Observable' Album[]>' 不可分配给类型 'Observable'

How do simulate the old operator .catch() behavior?如何模拟旧的 operator .catch()行为?

Update:更新:

After mucking around with this a bit more, the code as shown just started working without giving me a build error.在对此进行了更多研究之后,所示代码刚刚开始工作,而没有给我一个构建错误。 Honestly I have no idea why it failed with the error message before, but is working now.老实说,我不知道为什么它之前因错误消息而失败,但现在可以正常工作了。 The suggestion by @cartant in the comments is an explicit way to specify the result and that works as well. @cartant 在评论中的建议是一种明确的方式来指定结果并且也有效。

You should be able to explicitly specify the type parameters to catchError to indicate that it won't return an observable that emits a value - that is, it will return Observable<never> - and will always throw: 您应该能够显式指定catchError的类型参数,以指示它不会返回发出值的observable - 也就是说,它将返回Observable<never> - 并且将始终抛出:

getAlbums(): Observable<Album[]> {
    return this.httpClient.get<Album[]>(this.config.urls.url("albums"))
        .pipe(
            map(albumList => this.albumList = albumList),
            catchError<Album[], never>(new ErrorInfo().parseObservableResponseError)
        );           
}

Doing so will see the type inferred from the pipe call to be Observable<Album[]> . 这样做会看到从pipe调用中推断出的类型是Observable<Album[]>

You can return a typed observable with:您可以返回一个类型化的可观察对象:

return of (new YourType({ }));

instead of代替

return throwError(()=>err);

For example:例如:

http.get<CustomType>().pipe(
  map(result=>{
    // do something here, such as accessing local storage, stopping a spinner...etc.
    return result;
  }),
  catchError(err => {
     return of (new CustomType({
 //initialization with a constructor
}));
    // or you can return throwError(err);
  })
)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 rxjs:如何从 catchError 返回另一个可观察的结果 - rxjs: how to return the result from another observable from catchError 我如何拦截一个可观察对象以获取值并仍然返回一个可观察对象? - how do i intercept an observable to get the value and still return an observable? RxJS - 在 catchError 块中使用 observable - RxJS - Using an observable in catchError block 如何测试角度 - catchError 运算符“rxjs” - HOW DO TESTING ANGULAR - catchError operator 'rxjs' 如何在catcherror中从订阅中返回已翻译的消息? - How do I return a translated message from a subscription in a catcherror? RxJs catchError 更改返回类型 - RxJs catchError changes return type 如何按顺序订阅并仅返回 RxJS 中最后一个 observable 的值? - How do I subscribe in sequence and return only the value from the last observable in RxJS? 如何在 Angular 中使用 catchError RxJS 运算符进行错误处理? - How to do ErrorHandling using catchError RxJS Operator in Angular? 如何在计时器(rxjs)中继续捕获错误 - How to continue catchError in timer (rxjs) RXJS 如何在另一个中使用一个可观察的结果(然后将这两个结果一起处理) - RXJS How do I use the result of one observable in another (and then process those two results together)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM