This lesson is for PRO members.

Unlock this lesson NOW!
Already subscribed? sign in

Combination operator: withLatestFrom

4:02 RxJS lesson by

Operator combineLatest is not the only AND-style combinator. In this lesson we will explore withLatestFrom, another AND-style combination operator, and how it works essentially as map() operator, with some combination properties.

Get the Code Now
click to level up

egghead.io comment guidelines

Avatar
egghead.io

Operator combineLatest is not the only AND-style combinator. In this lesson we will explore withLatestFrom, another AND-style combination operator, and how it works essentially as map() operator, with some combination properties.

Avatar
Rafael

I'm pretty sure I have the exact same code as you do and for some reason I get 'helLo' printed out, so just the second 'L' is set to upper case. Anyone else getting this?

edit: yep, just checked and even copying the code from this class and running it on JS Bin, the result is always 'helLo'. This behavior makes more sense to me anyways.

In reply to egghead.io
Avatar
Andre

Rafael, try different combinations of interval numbers (300 and 500) because in cases where two events happen "at the same time", RxJS might not be that precise since both intervals are scheduled with setInterval. What is important here is that withLatestFrom itself is not broken.

In reply to Rafael

There are other combination operators that work like CombineLatest. One of them is withLatestFrom, and it's curious that it's also an and style combination operator. CombineLatest is still the most common and most important and combinator, but it's not the only one. WithLatestFrom is similar because it also takes a function that works on those values.

Whenever you have a combination operator that takes a function like this, it means that it's an and style combinator. Let's see how withLatestFrom works and why is it useful. Sometimes you have an observable, which you want to simply map. Let's say this observable would be an observable of characters like this saying, "Hello."

Suppose that this is being emitted by some text input field, for instance, and then you want to map that to just the upper case version of those characters. You can do this with a map, but let's say now that we want to conditionally map. Sometimes, it's lower case, sometimes it's upper case depending on another observable.

Let's say that we have this other observable bar, which admits the number zero and one. This is bar. What we want to do is we want to map each of these characters to upper case only if the latest value from bar was one. We want to map it to lower case if the latest value from bar was zero. In this case here, since the latest value from bar is zero, I want to map this to lower case.

Here, the latest value from bar is zero, I want to map it to lower case. Here, the latest value from bar was one, I want to map it to upper case. Same thing again, I want to map it to upper case. Finally here, I want to get the latest value from bar, It's zero, and I want to map it to lower case.

This is still a combination. We're combining these two observables, but essentially we're still just mapping foo to something. That's what withLatest does. You can actually think of it as map withLatestFrom. The map is sort of implicit, but it's called withLatestFrom and you provided a function of characters and numbers, characters come from foo and numbers come from bar.

We map that to, well, it depends. If the number is one, we want to map the character to its upper case version. Otherwise, we want to map that character to its lower case version. This is what withLatestFrom will do.

Let's try using it in practice here, and we hit that function to combine the values. Let's run this, and we see there a lower case "H," lower case "E-L-L-O," just like we had outlined here. We use withLatestFrom to map an observable, foo, to another observable, but using the latest value from some other observables.

That is why there is no static version of the withLatestFrom operator. That's because foo here is somehow special. It's different. It's assuming a different responsibility than bar is because essentially it's not like CombineLatest. If we would use CombineLatest, then when one is emitted on bar, it would be combined with latest value from "H" and that would make upper case "H," but that's not what we want.

We want basically this to be a mapping of that observable, just using some secondary information from other observables. The main observable is foo, that's what we want to map. That's why foo here is special because it's the main observable and we just want to use secondary information from other observables.

HEY, QUICK QUESTION!
Joel's Head
Why are we asking?