Extract pipeable operator as function in RXJS

Viewed 649

I have the following code

this.form.valueChanges.pipe(
    take(1),
    map(val => // doSomething),
    exhaustMap(val => 
      // someInner observable logic
      return of({someValue})
    )
).subscribe(finalVal => doSomething());

Now this code in the exhaustMap is repeated in several components and I'd like to extract it as an external function.

I have tried the following

  myExhaust(obs: Observable<any>): Observable<{ someValue: SomeClass }> {
    return obs.pipe(
      exhaustMap((val) => { 
           // do some stuff
           return of({someValue})
      })
    );
  }

But then I dont know how to plug it in the original code (that if the function code itself is correct)

4 Answers

You are basically creating a custom operator. You are on the right track. You have to make a function that takes an observable and returns a new one.

function myExhaust<T>(): MonoTypeOperatorFunction<T> {
    return input$ => input$.pipe(
       exhaustMap((val) => { 
           // do some stuff
           return of({someValue})
       }))
}

Now you can use myExhaust instead of exaustMap in your pipe.

Your utility seems fine and here's how you can pass the utility to the pipe:

this.form.valueChanges.pipe(
take(1),
 myExhaust,
).subscribe(finalVal => doSomething());

Here's the working example

You can create a regular shared function with this logic and use it in any components:

// set appropriate generic types for your case
// it's just an example 
export function fun<T>(data: T): Observable<T> {
  // do your stuff
  return of<T>(data);
}

// usage
this.form.valueChanges
  .pipe(
    take(1),
    map(val => // doSomething),
    exhaustMap(val => fun(val))
  )
  .subscribe(finalVal => doSomething());

But if you need to combine this logic only with exhaustMap operator you need custom pipeable operator.

Related