Join egghead, unlock knowledge.

Want more egghead?

This lesson is for members. Join us? Get access to all 3,000+ tutorials + a community with expert developers around the world.

Unlock This Lesson
Become a member
to unlock all features

Level Up!

Access all courses & lessons on egghead today and lock-in your price for life.


    Control the Output of Values with RxJS Operator withLatestFrom

    André StaltzAndré Staltz

    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.



    Become a Member to view code

    You must be a Member to view code

    Access all courses and lessons, track your progress, gain confidence and expertise.

    Become a Member
    and unlock code for this lesson




    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.