AngularDebutant
AngularDebutant

Reputation: 1576

Extract pipeable operator as function in RXJS

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)

Upvotes: 2

Views: 1361

Answers (4)

user3818229
user3818229

Reputation: 1617

You can use pipe function to combine existing operators:

import { pipe } from 'rxjs';
import { filter, map } from 'rxjs/operators';

function discardOddDoubleEven() {
  return pipe(
    filter((v) => !(v % 2)),
    map((v) => v + v)
  );
}

Please refer the official documentation for the details: https://rxjs.dev/guide/operators#use-the-pipe-function-to-make-new-operators

Upvotes: 0

Basheer Kharoti
Basheer Kharoti

Reputation: 4292

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

Upvotes: 1

T. van den Berg
T. van den Berg

Reputation: 364

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.

Upvotes: 4

vadimk7
vadimk7

Reputation: 8285

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.

Upvotes: 0

Related Questions