Reputation: 49
I am new to RxJS and I am unable to figure out how the parameters are being passed:
import { catchError, map, Observable, of } from 'rxjs';
let obs$ = of(1,2,3,4,5);
obs$.pipe(
map(n => {
if (n === 4) {
throw 'bloody hell'
}
return n;
}),
catchError(handleError())
).subscribe(x => console.log(x));
function handleError() {
return (err: any, caught: Observable<any>): Observable<string> => {
console.log('error is ', err);
return of('I', 'II') ;
}
}
Output is
$ node build/catch-me.js
1
2
3
error is bloody hell
I
II
Now when I look at the catchError function it states:
export function catchError<T, O extends ObservableInput<any>>(
selector: (err: any, caught: Observable<T>) => O
): OperatorFunction<T, T | ObservedValueOf<O>>;
My questions are:
Upvotes: 2
Views: 307
Reputation: 8022
My questions are:
- How does the handleError magically get the err and caught values from catchError function? It is not being passed anywhere?
The catchError function doesn't have any direct relationship to the "err and caught value." Well, it does but only statically. It just needs to return a function of the correct type.
Or, if you're Haskell Curry you might say that handleError takes it's arguments separately and you're only seeing the partial application. The ret of the application happens inside catchError
Consider the following:
function add(a,b) {
return a + b;
}
function curry_add(){
return a => b => a + b;
}
const ten = add(9,1);
const alsoTen = curry_add()(9)(1);
curry_add
isn't magically getting any parameters. It's the same as add
, but it requires 3 applications before you can get a number out.
- Why is it that the err and caught values are available only in the return function of the handleError?
Partial application again, you can think of them as the second application of handleError
instead if you want. Giving you those values is the job of the catchError
operator, so you perform the first application and the operator performs the second behind the scenes.
- Are there two types being passed - one is the Type of the observable, the second the ObservableInput?
The error and the observable that emitted the error.
- How is one to understand what is the operaterfunction that is being returned from catchError? Finally one is returning an observable with values I, II.
An OperatorFunction
transforms an observable. The pipe
function only knows how to deal with OperatorFunction
s so every every operator ends up creating an OperatorFunction
. So map, tap, switchMap, catchError, etc all have the job of creating an OperatorFunction
for you. You can just create one on your own if you want.
for example:
function filterFours(a: Observable<number>): Observable<number> {
return new Observable(observer => {
const sub = a.subscribe({
next: v => {
if (v != 4) observer.next(v);
},
complete: () => observer.complete(),
error: e => observer.error(e)
});
return {
unsubscribe: () => sub.unsubscribe()
};
})
}
of(1,4,2,4,3,4,5,4).pipe(
filterFours
).subscribe(console.log);
this is semantically the same:
of(1,4,2,4,3,4,5,4).pipe(
filter(v => v != 4)
).subscribe(console.log);
So the thing that filter(v => v != 4)
returns is the same kind of thing that filterFours
is. They do the same thing.
Upvotes: 1
Reputation: 21638
handleError is a function that returns a function. That function is what is passed into the catchError. It is the same as
catchError((err: any, caught: Observable<any>): Observable<string> => {
console.log('error is ', err);
return of('I', 'II') ;
})
as that is the function handleError returns.
Upvotes: 1