#Conditional Observables using iif and Subjects

11 messages · Page 1 of 1 (latest)

sage galleon
#

Hi, I would like to perform some chained effects on elements based on the status of my modal

To chain calls, I would like to use concatMap to queue execution, but also iif to conditionally run one pipeline or another

So far I am using BehaviorSubjects to achieve the following:

  readonly #closeModal$ = new Subject<void>();
  readonly #openModal$ = new Subject<void>();

  constructor() {
    this.#closeModal$
      .pipe(
        takeUntilDestroyed(),
        tap(() => this.#htmlEl.classList.add("modal-is-closing")),
        delay(modalAnimationDuration),
        tap(() => this.isModalOpen.set(false)),
        tap(() => this.#htmlEl.classList.remove("modal-is-open", "modal-is-closing"))
      )
      .subscribe();

    this.#openModal$
      .pipe(
        takeUntilDestroyed(),
        tap(() => this.isModalOpen.set(true)),
        tap(() => this.#htmlEl.classList.add("modal-is-open", "modal-is-opening")),
        delay(modalAnimationDuration),
        tap(() => this.#htmlEl.classList.remove("modal-is-opening"))
      )
      .subscribe();

    toObservable(this.open)
      .pipe(
        takeUntilDestroyed(),
        skip(1),
        // 👇 This does not queue anything
        tap((shouldOpen) => (shouldOpen ? this.#openModal$.next() : this.#closeModal$.next())),
      )
      .subscribe();
  }

However, this is not taking advantage of RxJS and instead calls tap, how can I change this so that my observable can look like the following:

    toObservable(this.open)
      .pipe(
        takeUntilDestroyed(),
        skip(1),
        // 👇 No more `tap` but rather Observables branching
        concatMap((shouldOpen) => iif(() => shouldOpen, this.#closeModal$, this.#openModal$))
      )
      .subscribe();

Thanks for the help and suggestions!

#

Conditional Observables using iif and Subjects

clear galleon
#

concatMap will subscribe to the inner observable, it will not call next on it.
Could explain a little bit more what you're trying to achieve?

sage galleon
#

That’s my issue, how can I convert the subjects’ associated pipelines to two observables on which I can call concatMap ?

#

I would like, depending on the initial flag, to conditionally call one pipeline or another

clear galleon
#

I'm not sure I'm getting the point of concatting them.

sage galleon
clear galleon
#

But if there's an external source, what's the point of them being subjects?

sage galleon
#

I wanted to represent the distinct pipelines internally and imperatively trigger them
What would you suggest for that behaviour?

clear galleon
#

If there's both an external source both the needs for an imperative command, I'd make them a combineLatest among a subject and an observable.

sage galleon
#

It’s a bit abstract for me, from the example, could you show me approximately what you have in mind?