Angular + RxJS : takeUntil
February 09, 2024
On this page we will learn to use RxJS takeUntil
operator in our Angular application. RxJS takeUntil
allows source observable to emit until the observable specified to takeUntil
emits a value. The observable specified to takeUntil
is notifier and once it emits its first value, source observable stops emitting and completes itself.
Here we will discuss
takeUntil
in detail with examples.
RxJS takeUntil
RxJStakeUntil
allows to emit values from source observable until the specified notifier observable emits a value.
takeUntil(notifier)
notifier is an observable and when it emits its first value, source observable stops emitting.
Returns
Returns an observable that emits the values of source observable until the specified notifier emits its first value.
1.
takeUntil
lets pass source observable emit until the another observable passed to it, starts emitting. Source observable stops emitting and marked as complete as soon as the observable passed to takeUntil
emits its first value.
2.
takeUntil
mirrors the source observable and emits the values emitted by source. At the same time takeUntil
also monitors the notifier observable specified to it. If notifier observable starts emitting, the source observable stops emitting and completes.
3. If notifier observable did not emit any value and completes, then source observable will emit all its values.
4. If notifier observable is taking longer time than the time taken by source observable to emit all its values, in this case, too, source observable will be able to emit all its values.
Example-1
Find the simple example oftakeUntil
operator.
interval(1000).pipe( takeUntil(timer(5000)) ).subscribe(v => console.log(v)); // Output 0, 1, 2, 3
interval(1000)
is an observable that will emit value after every second for infinite. We have specified timer to takeUntil
operator. timer(5000)
returns an observable that will emit notification after 5 seconds. takeUntil
will allow source observable created by interval(1000)
to emit only up to 5 seconds and after that source observable will complete. Within 5 seconds source observable will emit 0, 1, 2 and 3 with one second interval.
Example-2
In this example we will allow to emit items for every click on button up to the given time. Here I am usinginterval
as notifier in takeUntil
operator. interval
keeps on emitting values for the given interval time. takeUntil
will stop emitting of source observable once interval
emits its first value.
import { AfterViewInit, Component, ElementRef, ViewChild } from '@angular/core'; import { fromEvent, interval, takeUntil, tap } from 'rxjs'; @Component({ selector: 'my-app', standalone: true, template: '<button #userclick>Click Here</button>' }) export class MyComponent implements AfterViewInit { @ViewChild('userclick') userClick!: ElementRef; ngAfterViewInit() { const clicks$ = fromEvent(this.userClick.nativeElement, 'click'); clicks$.pipe( takeUntil(interval(6000)), tap(v => console.log("User clicked.")) ).subscribe(output => console.log(output)); } }
In this demo
fromEvent
creates an observable that emits click event coming from the button click. This observable will complete emitting in 6 seconds. This is because the notifier interval(6000)
will emit first value after 6 seconds that will cause takeUntil
to stop source observable emission and complete it.
takeUntil vs takeWhile vs takeLast vs take
1. takeUntil : Allows the source observable to emit until the specified notifier emits a value.interval(1000).pipe( takeUntil(timer(6000)) ).subscribe(e => console.log(e)); // 0, 1, 2, 3, 4
interval(1000)
emits items until the timer(6000)
emits notification. It means source observable will emit up to 6 seconds. The output will be 0, 1, 2, 3, 4 .
2. takeWhile : Allows the source observable to emit so long as each value satisfies the given predicate.
interval(1000).pipe( takeWhile((v, i) => i < 3) ).subscribe(v => console.log(v)); // 0, 1, 2
3. takeLast : Emits the last N elements once the source observable is complete.
of(101, 102, 103, 104).pipe( takeLast(2) ).subscribe(v => console.log(v)); // 103, 104
takeLast(2)
will allow to emit last 2 elements from the source observable and hence output will be 103 and 104.
4. take : Emits only first N elements emitted by source observable.
of(101, 102, 103, 104).pipe( take(3) ).subscribe(v => console.log(v)); // 101, 102, 103
take(3)
will allow first 3 elements to emit from source observable. Hence output is 101, 102 and 103.