24 Jul 2024
5 min

takeUntil – RxJS Reference

takeUntil

takeUntil passes values from the source observable to the observer (mirroring) until a provided observable known as the notifier emits its first value. The operator subscribes to the source observable and begins mirroring the source Observable. It also subscribes to the notifier observable. If the notifier emits a value, takeUntil unsubscribes from the source and notifier observables and completes. If the notifier doesn't emit any value and completes then takeUntil will pass all values.

Note, that if you only need to take a specific number of values from the source observable, you should use take operator.

The operator works in the following way:

  1. Subscribe to both a source and notifier observables
  2. When a new value arrives from a source observable, send it to the observer
  3. If the notifier observable emits a value, unsubscribe from both observables, send the complete notification to the observer
  4. Once the source observable completes, send the complete notification to the observer
  5. If the source observable throws an error, send the error notification to the observer

Usage

takeUntil is mostly used to avoid memory leaks and clear resources once a certain even happens. In a component based application, takeUntil can be triggered by the event of a component destruction through a notifier observable. This notifier observable is commonly implemented as a Subject.

Here’s an example that demonstrates this logic:

const stream = interval(1000);

function component(source) {
   const notifier = new Subject();

   source.pipe(
       takeUntil(notifier)
   ).subscribe(render);

   return () => {
       notifier.next(null);
   };
}

const destroy = component(stream);

setTimeout(destroy, 3000);

function render(v) {
   const text = document.createTextNode(v);
   document.body.appendChild(text);
}

Playground

Additional resources

See also

Frequently asked questions

How does takeUntil work in RxJS?

takeUntil mirrors values from the source observable until a notifier observable emits its first value. When the notifier emits, takeUntil unsubscribes from both the source and the notifier and sends a complete notification to the observer. Until then, every value from the source is passed through unchanged.

How do I unsubscribe from an RxJS observable when a component is destroyed with takeUntil?

Create a Subject as a notifier, pipe your source through takeUntil(notifier), and call notifier.next() when the component is destroyed. Calling next() makes takeUntil unsubscribe from the source and complete, which prevents memory leaks. Triggering this from a destroy callback, such as a function returned by the component, is the typical way to clear resources on teardown. For lifecycle or user-triggered stops, a notifier such as a Subject is the right tool.

What is the difference between take and takeUntil in RxJS?

Use take(n) when you only need a specific number of values, and takeUntil(notifier) when completion depends on an external event. takeUntil keeps mirroring the source indefinitely until its notifier emits, regardless of how many values have arrived. For lifecycle or user-triggered stops, a notifier such as a Subject is the right tool.

What happens if the takeUntil notifier completes without emitting a value?

If the notifier completes without emitting any value, takeUntil passes all values from the source through. Only a notifier emission stops the source, so a notifier that completes silently never interrupts it. The source then controls completion: takeUntil finishes when the source completes and forwards its error if the source throws.

How does takeUntil handle errors from the source observable?

When the source observable throws, takeUntil sends the error notification straight to the observer. The operator does not catch or retry it, so errors from the source reach the observer's error callback just as they would without the operator. The notifier has no role in this path.

Share this post

Sign up for our newsletter

Stay up-to-date with the trends and be a part of a thriving community.