1

This question is for learning purposes, not to solve a particular problem (please move it to the appropriate section if necessary).

I'm learning about piping operators in the RxJS library. At this site here (https://rxjs.dev/guide/operators) it distinguishes between pipeable operators and creator operators.

It defines pipeable operators as follows:

A Pipeable Operator is a function that takes an Observable as its input and returns another Observable. It is a pure operation: the previous Observable stays unmodified.

And it defines creator operators as follows:

Creation Operators are the other kind of operator, which can be called as standalone functions to create a new Observable. For example: of(1, 2, 3) creates an observable that will emit 1, 2, and 3, one right after another.

But this leaves me wondering: is there such an operator as one that DOES modify the observable it gets as input and returns it as output? I haven't come across anything like that. Is there a reason such an operator doesn't exist? What kind of undesired behavior would result from such an operator?

gib65
  • 1,709
  • 3
  • 24
  • 58
  • 1
    Rx is a pure library. None of the pipeable operators change the previous observable. If such an operator existed it would have the ability to break existing pipelines in unpredictable ways - that would give you exceedingly hard to diagnose bugs. – Enigmativity Jun 29 '21 at 03:25
  • I don't even think it's possible to create an operator that would modify its source Observable. Maybe if each emission was an object and you would modify the same instance in your operator than it would do something similar to what you're asking(?). – martin Jun 29 '21 at 07:25

1 Answers1

1

You can see pipable operation as a series of function execution, in most of the time there's no need for modifying the upstream function. What we interest in is transforming data and add custom operation as we proceed down the stream

fn(fn2(fn3(...)))

if in any case you want to modify upstream behavior, the upstream observable has to be designed to allow such case, for instance use a function factory to let user add an middleware

e.g

const interceptor=()=>{...}
const getUpstreanFn=(middleware)=>(param)=>{ middleware()......}
const upstreamFn=getUpstreamFn(middleware)
Fan Cheung
  • 10,745
  • 3
  • 17
  • 39
  • Would the following be a good example of undesired behavior if operators modified the original observable? `obs.subscribe(x => console.log('one:', x)); obs.pipe(map(x => x*2)).subscribe(x => console.log('two:', x)); obs.subscribe(x => console('three:', x));` Say the map operator modified the original observable. And say the observable emitted the value 1. Then the output might be `one: 1 two: 2 three: 2`. IOW, once the map operator runs, it multiplies the original value by 2 and subsequent subscriptions will receive the modified value (not necessarily in the order I depicted). – gib65 Jul 06 '21 at 03:24
  • `map` here does not modified the original observable - `obs`. This is append not modifying. let say if we work together on this piece of code, and i don't need your additional `map` in my logic, I can just directly use `obs` to create my own stream e.g `obs.pipe(switchMap(...)).subscribe()`, `obs` remains intact. – Fan Cheung Jul 06 '21 at 06:15