First, Last & Single Operator In Angular
In this article, we will learn about the First, Last, and Single RxJs operators in Angular Observable. To check the values of the source observable, all three operations use the predicate (condition). The first emits the first matching value, the final emits the last matching value, and the single emits only if there is a single value that matches the criteria.
First Operator
The first operator outputs the first value that matches the criteria. It will emit the first value it receives if no condition is given.
Syntax
first<t d="">(predicate?: (value: T, index: number, source: Observable<t>) => boolean, defaultValue?: D) : OperatorFunction<t d="" t="">
Where
predicate: is the condition that must be a match
defaultValue: If no value matches the condition, this is the value to emit.
- If no predicate is specified, the first value is returned.
- If the predicate is present, emits the first matched value.
- After emitting a value, closes the stream.
- If the source completes without emitting any matching value, the error message is raised.
Example
Using the of operator, we create an observable in the following example. The first operator emits the first value it receives, which is 1, before finishing.
import { Component, VERSION } from "@angular/core"; import { timer, interval, of } from "rxjs"; import { first } from "rxjs/operators"; @Component({ selector: "my-app", templateUrl: "./app.component.html", styleUrls: ["./app.component.css"] }) export class AppComponent { src = of(1, 2, 3, 4, 5).pipe(first()); id = Date.now(); constructor() {} ngOnInit() { console.log("Component Created " + this.id); this.src.subscribe(value => { console.log(value); }); } } *** Result **** 1
The first value that matches is emitted.
src = of(1, 2, 3, 4, 5).pipe(first(val => val > 3)); **Result** 4
The code below throws an error because no value matches the condition.
src = of(1, 2, 3, 4, 5).pipe(first(val => val > 10)); ***Error no elements in sequence
However, if no value matches the condition, the default value will be emitted first.
src = of(1, 2, 3, 4, 5).pipe(first(val => val > 10,100)); ***Console** 100
The following generates an error as well because the source does not emit any values.
src = of().pipe(first()); ***Error no elements in sequence
The default value of 100 is emitted as follows.
src = of().pipe(first(val => true, 100)); ***Console 100
First Vs Take(1)
The first() and take(1) methods return the first value received from the source and close the observable, respectively.
When the source does not emit anything, however, they behave differently. Take(1) does not emit anything but closes the observable, whereas first() sends an error notification.
Last Operator
The last operator returns the most recent value that fulfills the criterion. It will emit the last value it receives if no condition is given.
Syntax
last<t d="">(predicate?: (value: T, index: number, source: observable<t>) => boolean, defaultValue?: D) :OperatorFunction<t d="" t="">
- Before emitting the value, it waits for the source to finish.
- If no predicate is present, it emits the latest value.
- If the predicate is present, emits the latest matching value.
- After emitting a value, closes the stream.
- If the source completes without emitting any matching value, the error message is raised.
Example
Using the of operator, we create an observable in the following example. The final operator emits the most recent value it receives, which is 5, and then completes.
import { Component, VERSION } from "@angular/core"; import { timer, interval, of } from "rxjs"; import { last } from "rxjs/operators"; @Component({ selector: "my-app", templateUrl: "./app.component.html", styleUrls: ["./app.component.css"] }) export class AppComponent { src = of(1, 2, 3, 4, 5).pipe(last()); id = Date.now(); constructor() {} ngOnInit() { console.log("Component Created " + this.id); this.src.subscribe(value => { console.log(value); }); } } **Console ** 5
The latest value that matches the predicate is emitted.
src = of(1, 2, 3, 4, 5).pipe(last(val => val < 3)); ***Console** 2
No value matches the condition, hence it returns an error.
src = of(1, 2, 3, 4, 5).pipe(last(val => val < 0)); *** Console ***** ERROR Error: no elements in sequence
With a default value, however, if no value meets the condition, it will emit the default value.
src = of(1, 2, 3, 4, 5).pipe(last(val => val < 0,0)); ***Console** 100
The following generates an error as well because the source does not emit any values.
src = of().pipe(last()); ***Error no elements in sequence
The default value of 100 is emitted as follows.
src = of().pipe(last(val => true, 100)); ***Console 100
Last Vs TakeLast(1)
takeLast(1) and last() (without condition & default value) return the last value received from the source observable.
When the source does not emit anything, however, they behave differently. TakeLast(1) does not emit anything but closes the observable, whereas last() sends an error notification.
Single
The Single operator returns only one value that satisfies the criterion.
- Before emitting the value, the Single operator waits for the source to finish.
- Emits a single value that satisfies the criteria.
- It raises an error warning if more than one value satisfies the requirement.
- If no value satisfies the criterion, the value undefined is emitted.
- If the source does not emit any value, the error notification is raised.
Syntax
single<t>(predicate?: (value: T, index: number, source: Observable<t>) => boolean): MonoTypeOperatorFunction<t>
Where
the predicate is the condition
Examples
Emits 3 because it is appropriate for the situation.
src = of(1, 2, 3, 4, 5).pipe(single(val => val == 3)); **Console 3
Waits for the observable to come to an end. As a result, the following will never return a value.
src = interval(1000).pipe(single(val => val == 3)); **Console*
Because there are multiple values that satisfy the criterion, an error is raised.
src = of(1, 2, 3, 4, 3).pipe(single(val => val == 3)); **Console** ERROR
The sequence contains more than one element
The Single operator emits undefined if the source does not emit any matching values. It's worth noting that it doesn't send out any error messages.
src = of(1, 2, 3, 4, 3).pipe(single(val => val == 5)); *Console* undefined
All values are matched by a single without any predicate. As a result, the error.
src = of(1, 2, 3, 4, 3).pipe(single()); ***Console*** ERROR
The sequence contains more than one element
There is only one value in the source, and there is no predicate. The value is emitted
src = of(1).pipe(single()); **Console** 1
Because the source is empty, an error message is displayed.
src = of().pipe(single()); **Console*** ERROR Error: no elements in sequence
Conclusion
In this article, we learned about the First, Last, and Single RxJs operators and how to use them in Angular Observable.
I hope this article helps you and you will like it.👍
If you have any doubt or confusion then free to ask in the comment section.