3
votes

I am in the process of upgrading to rxjs v6 from 5, I have also upgraded my typescript version from 2.9.2 to 3.7.4. In one of my angularjs components, I make a call to a service that returns a promise. For ease of use, I convert that into an observable in my component by using the from rxjs function. My code looks like this (with names changed from originals).

saveObject(name: string): Observable<void> {
    return from(
            this.myService.saveMyObject(name)
                .then(() => {
                    //Show Save success on ui
                    return;
            }),
        )
        .pipe(
            catchError((error) => {
                // error handling logic
                return of(); // this bit was an attempt to fix the problem
            }),
        );
}

The problem I am having is that the saveObject function in the component returns an observable of void, the promise ultimately resolves to void but when I try to return the observable I get an error saying that observable< unknown> is not assignable to observable< void>. Why is typescript/rxjs inferring the type to be unknown and is there anything I can do aside from doing type assertion to get the correct type.

Edit: Removing the pipe altogether does not fix the issue, just the from(promise) is enough to get the error, unfortunately even doing this to tell rxjs that it is an promise of void does not help, it still offers the same error.

from<Promise<void>>(//promiseCode)
3

3 Answers

1
votes

try return of() to complete the observable and see if it works.

from(this.myService.saveMyObject(name))
.pipe(
    mergeMap(()=>of()),
    catchError((error) => {
        // error handling logic
        return of(); // this bit was an attempt to fix the problem
    }),
);
1
votes

With the help of someone on the rxjs team I discovered it was because I needed to include this option in my tsconfig file.


    "lib": ["es2015"],

0
votes

That is because the catchError() operator requires you to return an observable. As stated on the documentation, catchError()

Gracefully handle errors in an observable sequence.

And you are required to return an observable.

:warning: Remember to return an observable from the catchError function!

If you do not want to return an observable, an alternative to using the catchError operator would be to handle the error on the error callback when you subscribe to the observable.

saveObject(name: string): Observable<void> {
  return from(
    this.myService.saveMyObject(name)
            .then(() => {
                //Show Save success on ui
                return;
        }),
    )

}

this.saveObject.subscribe((res) => {
  // handle success
}, (error) => { 
  // handle errors, without the need to return an observable
});