1

In most of my API calls I use this pattern:

  1. call server and pipe result

  2. Check for error and throw if needed

  3. map results from server

    public getItems() : Observable<Item[]> {

      return this.http.get<Item[]>>(environment.url + '/items').pipe(
    
             catchError((error:any)=> throwError('Failed getting items')),
    
             map((ret)=> this.mapResults(ret)));
    

    }

Is there a way to merge the catchError and map operators to a single operator ?

Something like this:

catchErrorAndMap("Message in case of error",itemForMapping)

itemForMapping will go into the mapping function. something like this?

 return this.http.get<Item[]>>(environment.url + '/items').pipe(
    
                catchErrorAndMap('Failed getting items'),ret));
Maayan Hope
  • 1,482
  • 17
  • 32

1 Answers1

4

Yes. An RxJS operator is just a function. So, you can write your own RxJS operators.

There is an example here: https://netbasal.com/creating-custom-operators-in-rxjs-32f052d69457

In the section entitled: "Creating Operators from Existing Operators".

So you can create a catchErrorAndMap function that you can then use as an operator.

Here is an example:

export function catchErrorAndMap(errorMessage): OperatorFunction<User[], User[]> {
  return source =>
    source.pipe(
      catchError((error: any) => throwError(errorMessage)),
      map(items => items.map(item => ({ ...item, name: item.name + "'s"} as User)))
    );
}

This creates a function that takes in an Observable<User[]> and returns an Observable<User[]>. You'd need to modify it as needed for your project. (Probably Item[]).

It then pipes the source (which is the emitted item from the source stream) through the desired operators.

In this example, I used a map operation appropriate for my data. You could of course change it to your this.mapResults().

You'd call this operator just like any other pipe operator:

  users$ = this.http
    .get<User[]>(this.userUrl)
    .pipe(catchErrorAndMap("Error Occurred"));
DeborahK
  • 57,520
  • 12
  • 104
  • 129
  • event when creating my own operator i will have to catch error before? .pipe( catchError((error:any)=> throwError('Failed getting available product importers')), catchErrorAndMap() ) – Maayan Hope Aug 21 '20 at 22:38
  • 1
    I added a more specific example to my post. – DeborahK Aug 21 '20 at 23:07