Starting out

You almost always start out coding with RxJS by creating a stream of static values. Why static values? Well, there is no need to make it unnecessarily complex, and all you really need to start reasoning is an Observable. As you gradually progress in your problem solving, you might replace the static values with a more appropriate call to an AJAX call, or from another asynchronous source that your values originate from.

You then start thinking about what you want to achieve. This leads you to consider which operators you might need and in which order you need to apply them. You might also think about how to divide your problem up; this usually means creating more than one stream, where each stream solves a specific problem that connects to the larger problem you are trying to solve.

Let's start with stream creation and see how we can take our first steps working with streams.

The following code creates a stream of static values:

const staticValuesStream$ = Rx.Observable.of(1, 2, 3, 4);

staticValuesStream$.subscribe(data => console.log(data));
// emits 1, 2, 3, 4

That is a very basic example of how we can create a stream. We use the of() creation operator, which takes any number of arguments. All the arguments are emitted, one by one, as soon as there is a subscriber. In the preceding code, we also subscribe to staticValuesStream$ by calling the subscribe() method and passing a function that takes the emitted value as a parameter. 

Let's introduce an operator, map(), which acts like a projection and allows you to change what is being emitted. The map() operator gets called on each value in the stream before it is emitted. 

You use the map() operator by supplying it with a function and carrying out a projection, like so:

const staticValuesStream$ = 
Rx.Observable
.of(1, 2, 3, 4)
.map(data => data + 1);

staticValuesStream$.subscribe(data => console.log(data))
// emits 2, 3, 4, 5

In the preceding code, we have appended the map() operator to staticValuesStream$ and we apply it to each value before emitting it and incrementing it by one. The resulting data is therefore changed. This is how you append operators to a stream: simply create the stream, or take an existing one, and append the operators one by one. 

Let's add another operator, filter(), to ensure that we really understand how to work with operators. What does filter() do. Well, just like the map() operator, it is applied to each value, but instead of creating a projection, it decides which values will be emitted. filter() takes a Boolean. Any expression evaluated to true means the value will be emitted; if false, the expression will not be emitted.

You use the filter() operator in the following way:

const staticValuesStream$ = 
Rx.Observable
.of(1, 2, 3, 4)
.map(data => data + 1)
.filter(data => data % 2 === 0 );

staticValuesStream$.subscribe(data => console.log(data));
// emits 2, 4

We add the filter() operator by chaining it to the existing map() operator. The condition we give our filter() operator says to only return true for values that are divisible by 2, that's what the modulus operator does. We know from before that the map()   operator alone ensures that the values 2, 3 , 4, and 5 are emitted. These are the values that are now being evaluated by the filter() operator. Out of those four values, only 2 and 4 fulfill the condition set out by the filter() operator.

Of course, when working on a stream and applying operators, things might not always be as simple as the preceding code. It might not be possible to anticipate exactly what gets emitted. For those occasions, we have a few tricks we can use. One such trick is to use the do() operator, which will allow us to inspect each value without changing it. This gives us ample opportunity to use it for debugging purposes. Depending on where we are in the stream, the do() operator will output different values. Let's look at different situations where it matters where the do() operator is applied:

const staticValuesStream$ = 
Rx.Observable.of(1, 2, 3, 4)
.do(data => console.log(data)) // 1, 2, 3, 4
.map(data => data + 1)
.do(data => console.log(data)) // 2, 3, 4, 5
.filter(data => data % 2 === 0 )
.do(data => console.log(data)); // 2, 4

// emits 2, 4
staticValuesStream$.subscribe(data => console.log(data))

As you can see, just by using the do() operator, we have a nice way to debug our streams, which becomes necessary as our streams grow in complexity. 

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset