-1

I'm using angular and rxJS I'm pretty new to rxJS operators and can't find a way to keep everything inside a stream.

My stream is pretty long so I'll get straigth to the point explaining the problem I'm dealing with

I need to run parralel Observables that can be triggered multiple times and process their data in the same manner, but their subscription needs to be in a certain order. for example

    firstObservable$.pipe(
      map(() => secondObservable$),//this will only be triggered once
      tap(value => doSomething(value)),//data is processed once following the stream
      mergeMap(() => ThirdObservable$),//this one will be triggered multiple times but is subscribed in a particular order
      tap(value => doAnotherThing(value)),//how can I attach the processing og data to the observable?
      mergeMap(() => FourthObservable$),//this one will be triggered multiple times but is subscribed in a particular order
      tap(value => andAnother(value)),//how can I attach the processing og data to the observable?
      map(() => FifthObservable$),//this will only be triggered once
      tap(value => again(value))//data is processed once following the stream
    ).subscribe()

now my problem is that if ThirdObservable$ is triggered as second time it will continue the rest of the stream and call FourthObservable$ and FifthObservable$ I would like the equivalent of

    firtsObservable$.subscribe( // triggered Once
      (value) => secondObservable$.subscribe( // triggered Once
        (secondValue) => {
          processSecondValueOnce(secondValue)
          ThirdObservable$.subscribe(thirdValue => process(thirdValue)) // this can be triggered multiple times
          fourthObservable$.subscribe(fourthValue => process(fourthValue)) // this can be triggered multiple times
          fifthObservable$.subscribe( // triggered Once
            (fifthValue) => {
              process(fifthValue)
            }
          )
        }
      )
    )

Owen Kelvin
  • 14,054
  • 10
  • 41
  • 74
JSmith
  • 4,519
  • 4
  • 29
  • 45
  • 2
    This sounds tricky to get right. Have you thought about architecting this differently? What other options have you thought about? – Shafiq Jetha Jan 14 '21 at 02:57
  • @ShafiqJetha I've thought about making all subscription called once follow one stream operator and for the other ones make them nested – JSmith Jan 14 '21 at 03:01
  • It looks you're looking for `switchMap` but I probably don't undestand how exactly this all should work – martin Jan 14 '21 at 08:35
  • hello @martin, first thank you for your interest in my problem. Basically I should be calling a ceratin number of observable in a certain order but certain ones should be triggered back independently from the stream in a sense that they shouldn't be triggering the other ones, third shouldn't be triggerring fouth and fifth when triggered again, does that make sense. Many thanks in advance... – JSmith Jan 14 '21 at 09:20

1 Answers1

1

If I understand right your question you may want to try something like this

firstObservable$.pipe(
  map(() => secondObservable$),
  tap(value_1 => doSomething(value_1)),
  mergeMap(() => {
     // create 3 separate observables, each doing its specific processing
     third = ThirdObservable$.pipe(tap(value => doAnotherThing(value));
     fourth = FourthObservable$.pipe(tap(value => andAnother(value));
     fifth = FifthObservable$).pipe(tap(value => again(value));
     // return the merge of the 3 observables
     return merge(third, fourth, fifth);
  })
).subscribe()

I have a point though I do not understand. In the first map operator you return an Observable (secondObservable$). This means that the variable I called value_1 will contain an Observable and therefore doSomething must be a function which expects an Observable as input. Is this what you really want?

Generally, in situations like this, you want to use "higher-order" operators like switchMap, mergeMap, concatMap or exaustMap. These are operators that expect, as input, a function which returns an Observable and "flatten" the return Observable. Maybe this is what you want as well.

Picci
  • 16,775
  • 13
  • 70
  • 113
  • thank you for your answer i'll have adeeper look later, I only hoped there would be a more "unique-stream" solution. Many thanks, btw I upvoted, thanks for your time – JSmith Jan 14 '21 at 11:16
  • I meant to trigger second observable then retrieve value, but I may be doing it wrong – JSmith Jan 14 '21 at 11:17