Despite the fact that Observables is its foundation, RxJS is most helpful for its operators. Operators are the key components that make the declarative composition of complicated asynchronous code possible. It is a kind of function and it is further categorized into two wider categories:
Creational Operators
Pipeable Operators
These operators are used most commonly in RxJS and by name, it’s clear that they are used to create. There are so many operators available, but two that are commonly used are from and of. So, let’s dive into it.
This operator is used to generate an observable from an iterable, an array, or a promise, as well as to direct the computer to supply the observable values from an existing data collection, such as an array. For a better understanding, consider the example below.
1 2 3 4 5 6 7 8 9
const { from } = require('rxjs'); const STRING_ARRAY = ["Hello World!", "This is", "an example", "of 'from' operator"]; const obs$ = from(STRING_ARRAY); //we subscribe by passing reference of console.log function obs$.subscribe(console.log);
Output –
This operator is the second most common creational operator. The “of” operator is identical to the “from” operator in terms of syntax, except instead of accepting iterative input like arrays, it accepts sequential data. If an array is returned, it is simply printed as a declarative statement. If the data makes sense in an array, of is the best option for wrapping observables.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
const { of } = require('rxjs'); const STRING_ARRAY = ["Hello World!", "This is", "an example", "of 'from' operator"]; const obsArray$ = of(STRING_ARRAY); console.log("\nIn case of iterative data source"); obsArray$.subscribe(console.log); const obsSequence$ = of("Hello World!", "This is", "an example", "of 'from' operator"); console.log("\nIn case of sequential data source"); obsSequence$.subscribe(console.log);
Output –
All operators except creational operators are called through the pipe() function. The second category of operators is pipeable operators, which are non-creational in nature.
To continue the pipeline, pipeable operators accept one observable as an input and return another as output. They can be invoked like any other function, for example, operator()(observable), but they’re more commonly used in a data pipeline. The pipe() method is the recommended way to invoke operators since it provides a cleaner approach to call numerous operators in a row.
1 2 3 4 5 6 7 8 9 10
//Standard way operator4()(operator3()(operator2()(operator1()(observable)))) //Using pipe function observable.pipe( operator1(), operator2(), operator3(), operator4() )
It’s recommended to use the pipe() method even if we have to invoke a single operator.
The filtering operator is the most popular pipeable operator. All values that don’t meet the requirements supplied to these operators are removed. We’ll look at the most popular filtering operators, such as first and filter.
The filter operator takes the predicate function as an argument, for example, value => value > 1. Every value in the iteration is passed first to that function, and only those values which make the function return true are kept. Other values that fail to do so are just ignored. Here is an example to filter out numbers ([1, 5, 10, 15, 20, 25]) that are greater than 10.
1
2
3
4
5
6
7
8
9
10
11
12
13
const {
filter
} = require('rxjs/operators');
const {
from
} = require('rxjs');
const obs$ = from([1, 5, 10, 15, 20, 25])
obs$.pipe(
filter(value => value > 10)
)
.subscribe(console.log)
Output –
A filter operator is an excellent tool for transforming data to meet the demands of individual subscribers. Some users, for example, might prefer to have all product listings, while others would just want to see products in a specific price range.
There are two ways to apply the first method. It returns the very first value of an observable by default. Returning the first value has the advantage of having a very short turnaround time, making it ideal for situations where a quick and simple response is all that is required.
1
2
3
4
5
6
7
8
9
10
11
12
const {
first
} = require('rxjs/operators');
const {
from
} = require('rxjs');
const obs$ = from([1, 5, 10, 15, 20, 25])
// Just take first
obs$.pipe(first())
.subscribe(console.log)
Output –
Another use of the first operator is to use the predicate function or default value to compare with the value passed to it. Just like a filter, first returns the first value to compare with a predicate. This becomes so helpful when we have to search a data stream and have the need for a single value.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const {
first
} = require('rxjs/operators');
const {
from
} = require('rxjs');
const obs$ = from([1, 5, 10, 15, 20, 25])
// Take predicate otherwise default
console.log("Returns first number which makes predicate true")
obs$.pipe(
first(value => value > 10, -50)
)
.subscribe(console.log)
console.log("Returns default as all numbers present are positive")
obs$.pipe(
first(value => value < 0, -50)
)
.subscribe(console.log)
Output –