Common Operators

Observables have a ton of operators to transform, filter, combine, split, deduplicate, etc. data emitted from the stream, but there are a handful that you will find yourself using all the time. This section attempts to explain the more commonly used operators.

Map

The map operator is analogous to a native JS array's map operator. It takes a function as a parameter that will be passed an item from the stream and return some value that will be emitted in its place downstream. It maps one value into another.

This is better examplained with examples. Let's look at this on an array:

const numbers = [ 1, 2, 3 ];
const mapped = numbers.map(x => `Number: ${x}`);

console.log(mapped);

The above will run the function x => `Number: ${x}` on each item in the array. The mapped variable will contain the results and look like: [ 'Number: 1', 'Number: 2', 'Number: 3' ].

Pretty simple, let's look at the observable version:

const myObs = Observable.from([ 1, 2, 3 ]);
const mappedObs = myObs.map(x => `Number: ${x}`);

mappedObs.subscribe(x => console.log(x));

Almost exactly the same. Map here is doing the same thing, applying the function to each item emitted on the stream. If we were to run this we would see Number: 1, Number: 2, Number: 3 printed out to the console.

That's all there is to it for map.

Try Me

Filter

The filter operator is again close cousins with its array counterpart. It takes in a function that runs over each item in the stream and returns a boolean value. If true the item is emitted as normal, if false, it is dropped from the stream.

Let's look at an example. Let's say you have an array of numbers and you want only the evens. We'll look at the array example and the observable example.

Array:

const numbers = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
const filtered = numbers.filter(x => x % 2 == 0);

console.log(filtered); // Outputs [ 2, 4, 6, 8, 10 ]

Observable:

const myObs = Observable.from([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]);
const filteredObs = myObs.filter(x => x % 2 == 0);

filteredObs.subscribe(x => console.log(x)); // Outputs 2, 4, 6, 8, 10

Pretty self explanatory.

Try Me

Reduce

Once again, the reduce operator is the same as it's array version. It takes in a function that will be used to combine the next item with the last, and returns the result. The purpose of reduce is to combine all elments of an array to a single value.

The function passed to reduce takes two parameters: the accumulated value, and an item from the array. Reduce can take a second parameter that will be used as the starting value for the accumulator. This is easier to understand if you see it in action.

const numbers = [ 1, 2, 3, 4, 5 ];
const reduced = numbers.reduce((acc, x) => acc + x, 0);

console.log(reduced); // Outputs 15

We pass reduce two parameters:

  1. The function (acc, x) => acc + x. This takes in the current value of the accumulator, the next item in the array, and returns the result of adding the accumulator to the item. This return value will be used as the accumulator value on the next run.
  2. The starting accumulator value of 0. On the very first item in the array, this will be the value of acc in the function above.

Now let's look at the observable version:

const obs = Observable.from([ 1, 2, 3, 4, 5 ]);
const reduced = obs.reduce((acc, x) => acc + x, 0);

reduced.subscribe(x => console.log(x)); // Outputs 15

Again, this is almost exactly the same as the array version. One thing to point out though, since reduce needs to know that it has every item that will be emitted from the stream before it is done, it will wait until the stream completes.

For example, if we change our code above to this:

const obs = Observable.interval(1000).map(x => x + 1).take(5);
const reduced = obs.reduce((acc, x) => acc + x, 0);

reduced.subscribe(x => console.log(x)); // Outputs 15

It will output 15 but only after five seconds have passed. This is because it is waiting for our observable to complete. The observal sends out a new value every 1 seconds until it has output 5 values. This is important to keep in mind when using reduce.

Try Me

Take

The take operator is our first that doesn't have a direct analog in native JS arrays, but it's pretty simple. You've already seen it used several times in examples, and it probably does what you expect. The only parameter take gets passed is a number, and it returns an observable that will automatically complete after that number of items has been emitted. Let's look at an example.

const obs = Observable.interval(1000);
obs.subscribe(x => console.log(x)); // Outputs 0, 1, 2, 3, 4, 5, 6, ... infinity

Try Me

The above observable will run until the heat death of the universe, emitting a number every one second for eternity.

const obs = Observable.interval(1000).take(5);
obs.subscribe(x => console.log(x)); // Outputs 0, 1, 2, 3, 4

TryMe

This observable is exactly the same as the first, but we've added take. It will automatically complete after 5 values have been emmitted.

There is an inverse to take called takeLast that will emit only the last n items from the stream. Similarly to reduce, it can't know what the last n items are until it completes, so be careful.

const obs = Observable.from([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]).takeLast(5);
obs.subscribe(x => console.log(x)); // Outputs 6, 7, 8, 9, 10

Try Me

results matching ""

    No results matching ""