distante
distante

Reputation: 7005

Is it possible to add observables to a combineLatest (or similar) at run time?

I have this use case. A component should NOT be visible when from a list of Boolean observables one of those is true. That is the easy part, for this, I have my service has an isBlocked$ public observable as API.

The hard part is that I need to register new observables at run time but keep my isBlocked$ reference so my current subscriptions do not break.

Example:

class MyService {
   isBlocked$: Observable<boolean> =  ?????

   
  add(observable: Observable<boolean>){
   }

}


// my component
...

myService.isBlocked$.subscribe(isBlocked => isBlocked)
// isBlocked = false
myService.add(of(true));
// isBlocked = true

Upvotes: 4

Views: 956

Answers (2)

maxime1992
maxime1992

Reputation: 23813

It is possible to achieve that yes.

You'll have to use a higher order operator like mergeAll

In your case it should be something like the following:

class MyService {
  observables$: Subject<Observable<any>> = new Subject();

  isBlocked$: Observable<boolean> = this.observables$.pipe(mergeAll());

  add(observable: Observable<boolean>){
    this.observables$.next(observable);
  }
}

If you need to handle the stream of streams differently than mergeAll, you can also check the following:
- concatAll
- zipAll
- switch

Edit:

As requested, here's an example: https://stackblitz.com/edit/rxjs-svzjk5

(Launch the app and open your console)

import { of, Subject, Observable, interval } from 'rxjs'; 
import { map, mergeAll, tap } from 'rxjs/operators';

const animals$$: Subject<Observable<string>> = new Subject();

const addAnimals = (animals: Observable<string>) => animals$$.next(animals);

const animals$: Observable<string> = animals$$.pipe(
  mergeAll()
);

// display the values in the stream
animals$.pipe(
  tap(console.log)
).subscribe()

// add some animals
addAnimals(
  interval(1000).pipe(map((i) => `Wolf ${i}`))
);
addAnimals(
  interval(1500).pipe(map((i) => `Cat ${i}`))
);
addAnimals(
  interval(600).pipe(map((i) => `Dog ${i}`))
);

Upvotes: 5

Tarun1704
Tarun1704

Reputation: 191

It is not possible to add observables to combineLatest in run time without having to modify the instance of the observable.

Upvotes: 0

Related Questions