Maximilian Körner
Maximilian Körner

Reputation: 894

RXJS: How to use takeUntil until another Observable completes (and not emits)

I have two Observables:

1: counts up a value and completes. (important: May complete before ever emitting any value!)

2: does stuff until 1 COMPLETES (not emits)

How would you implement this in RxJS?

My first try is using last() like:

firstObservable.pipe(
    takeUntil(secondObservable.pipe(last()))
  ).subscribe(count =>{
    //do stuff with count
  });

But the prroblem arises when firstObservable completes without ever emitting any value. An error is raised:

Error: no elements in sequence

Question: How can i use takeUntil (or any other operator) to stop the subscription after observable 2 completed and not throw an error when no last value ever was emitted?

Upvotes: 6

Views: 2906

Answers (3)

Narcis
Narcis

Reputation: 5918

Materialize the observable in order to receive notifications of type: Next, Error, Complete. Then simply filter them out.

 takeUntil(yourObs$.pipe(materialize(), filter(x=> x.kind === 'C'))))

Upvotes: 1

Matthew Marichiba
Matthew Marichiba

Reputation: 2092

I've been using a pattern that I find useful to trigger takeUntil() with arbitrary events. You basically create a 2nd observable "terminateSignal$" that you control directly.

const terminateSignal$ = new Subject<void>();
secondObservable.subscribe({
  complete: () => terminateSignal$.next()
});

firstObservable
  .pipe(takeUntil(terminateSignal$))
  .subscribe( /* do stuff */ );

Upvotes: 1

mat.hudak
mat.hudak

Reputation: 3163

You can use finalize on the secondOvservable and complete the firstObservable there. That way it does not depends on any value emitted, just on the complete event.

secondOvservable.pipe(
  finalize(() => firstObservable.complete())
).subscribe(count =>{
  //do stuff with count
});

Upvotes: 3

Related Questions