Advanced Asynchronous JavaScript Advanced Asynchronous JavaScript

Challenge 1: Map() for Observables

Learning Paths:
Check out a free preview of the full Advanced Asynchronous JavaScript course:
The "Challenge 1: Map() for Observables" Lesson is part of the full, Advanced Asynchronous JavaScript course featured in this preview video. Here's what you'd learn in this lesson:

Starting with the map() function, Jafar starts building common functions such as fiter() and reduce() with observables. After taking questions from the class, he prompts students to complete the challenge.

Get Unlimited Access Now

Transcript from the "Challenge 1: Map() for Observables" Lesson

[00:00:00]
>> Jafar Husain: We've built ourselves some factory functions for observables, but what about the most common functions that we actually use? The ones that you guys learned in the last class? MAP, filter, reduce, zip, etc. So let's try and build some of those. What I love about this is that really, once you guys see what's going on under the hood, and we step through it with the debugger, you're gonna have a much more solid understanding of how observable works.

[00:00:25] And you're also gonna see that there's not that much to it. It's actually pretty simple. So let's build ourselves my favorite function, map. So notice that the previous two functions have been static. Because they've been factory functions, right? They don't work on an observable, they create an observable.

[00:00:44] But map is different. Map works on an observable. So if you remember how we use map, bear with me here.
>> Jafar Husain: I can have an observable. Let's say I have some observable. I can map it. And I can take all the numbers in that observable and increment them by 1, right?

[00:01:03] So that's how map works. So let's write the map function. So what's the signature of map? What function? What does it take?
>> Speaker 2: It takes a function.
>> Jafar Husain: Sometimes it's called the projection function.
>> Jafar Husain: It takes an item and it turns it into a new item, all right?

[00:01:24] And what does map return?
>> Speaker 2: A non-observable.
>> Jafar Husain: Non-observable, right? Good default answer. All right, and so we're gonna define the subscribe method here. So for this observable we're returning, we're now defining what happens when they call subscribe. So guys, what happens when I call subscribe?
>> Jafar Husain: Let's write a little program.

[00:01:52] Let's go and actually add, so we can play around here, I'm gonna add a little button on screen.
>> Jafar Husain: There our, should be a button.
>> Jafar Husain: There it is.
>> Jafar Husain: So we have a nice button. And let's take the clicks on that button and turn them into an observable.

[00:02:35] So just before we write map, we'll just build ourselves an observable we can play around with and transform.
>> Jafar Husain: And,
>> Jafar Husain: Try and make this bigger for the folks at home.
>> Jafar Husain: Help me out, guys, what am I gonna do here to make a clicks observable?
>> Jafar Husain: What do I have to pass in here?

[00:03:19]
>> Speaker 2: Event name?
>> Jafar Husain: Yeah, the event name, right. Notice what I did here? It's plural. I tend to name my observables just like I name my arrays, because I want us to get out of the mode of thinking about events as this thing we hook up to, and this weird thing we unhook from.

[00:03:37] It's just a collection,, it's just a stream, all right? So now we created ourselves a stream of all the future clicks. Is this a steam that's infinite, or finite?
>> Speaker 2: Infinite.
>> Jafar Husain: Infinite, right?
>> Speaker 2: No dollar sign?
>> Jafar Husain: That is a convention that a lot of people use.

[00:03:55] I don't have anything against it, really, but I don't. So feel free to use that if you like. For those of you at home who don't know what he's talking about, some people use this convention to denote observable. I think it's clever. A little too clever for me.

[00:04:11] So I'm gonna stick with that. So now we have a clicks observable, so let's just actually quickly make sure this works before we jump on a map.
>> Jafar Husain: Cool.
>> Speaker 2: Can you now save it so that we can pull in the recent changes?
>> Jafar Husain: Seems reasonable. I saved the snapshot, hopefully that works.

[00:04:40]
>> Speaker 2: No, it's a different URL, no?
>> Jafar Husain: So I'm not as experienced with doing this in a shared way. Is it adifferent URL? Looks the same to me, but-
>> Speaker 2: It's with the, cuz you got the html, yeah. It's the output.
>> Jafar Husain: Cuz the output window is open.

[00:05:01] But I wouldn't expect that would impact that your ability to see the content. So I mean, I can keep saving a snapshot. But it's probably the best I can do I'm afraid.
>> Jafar Husain: If anybody can see it if they can help him out, that'll be awesome.
>> Jafar Husain: So this is kind of what we expect, no big surprises here.

[00:05:31] And actually I am gonna do this just one more time just to drive it home, make sure we all understand. I'm gonna step through this flow here and see how this happens.
>> Jafar Husain: Start by can we get to clicker observable there?
>> Jafar Husain: That really doesn't want to work.

[00:06:06]
>> Jafar Husain: Hit debugger that time.
>> Jafar Husain: There we go. So what happens when we step in to subscribe? Well, we jump all the way up to that wrapper subscribe method. We're always gonna find ourselves in there, that's no big deal. And then we're gonna hop in to real definition, so this what happens when you subscribe to our clicks.

[00:06:30] We create this handler function which closes over the observer, and it's gonna keep it alive as long as somebody has a handle onto this function. So our observable will stay alive. We add an event listener, and then we're done, right? That's all there is to do. But, since all the fun happens inside of our handler, I'm gonna put a break point right here, and we'll see what happens when we call, when we press the button.

[00:06:54] Now, we find ourselves into the handler, and we're gonna pump a value into that observer. I'm gonna step into next here, and we find ourselves in the real log function.
>> Speaker 2: We had a question on chat if you wanna check it out.
>> Jafar Husain: Yeah.
>> Speaker 2: Yeah.
>> Jafar Husain: Doesn't a hot observable never complete?

[00:07:17]
>> Speaker 2: Yeah, that was earlier, and then there's another one too.
>> Jafar Husain: So a hot observable absolutely can complete.
>> Jafar Husain: You can just miss the boat, right? Ideally, what would happen is if a hot observable completes, it would usually, a well behaved observable would remember that fact so that if subsequent subscribers come along, it just [SOUND] instantly completes for them so they don't just leak memory.

[00:07:43] That's how you would expect an observable to behave, all right, if a hot observable completes. So if you had a network request as a hot observable and somebody subscribed, and the network request came back and then it completed, you would expect the next person to come along to subscribe, to just immediately completely.

[00:08:00] Another thing it coul do is it could store away the result. And then give them result and then complete, right? And so it's possible for a hot observable to complete. Just means you gotta be all the quicker to get that data. And then isn't dollar sign EL for wrapped ELS like with jQuery?

[00:08:20] I think the question is asking, isn't the convention dollar sign used for jQuery? It is in the convention there. It's the actually identifier of the jQuery library. I think the only reason why people suggest using the dollar sign here is that it just makes it clear that it's an observable, as opposed to an array or some other, or generator, or some other vector like type with a lot of items.

[00:08:44] And it's kind of clever cuz the dollar sign looks like an s. So has nothing to do with jQuery. Don't worry about that. Let's write ourselves a map function to map our events. Now one thing about a click is, we can actually see, bear with me here, we can see it's actually got a lot of stuff in there.

[00:09:10] So instead of just writing next, I'm actually gonna log the event object itself.
>> Jafar Husain: Well, that seems like the JSON string FIDE event object. That's a lot of stuff, right? That's gonna be hard to see in the console right there. So why don't we just pluck off one property, or something like that, right?

[00:09:37] Maybe the client x, which is where on the button it was clicked. We can do that. What's a good function we can use to do that? Well, map, right? Map is great for taking objects and just grabbing little pieces off of them. So I'm gonna write map, and, right, we're back to where we were now.

[00:10:00] So we're gonna try and use map to pluck off just the piece that we want. So in this case, we are gonna pluck off the clientX property. Which is the X position on the button where it was clicked. I think it is either offsetX or clientX. And then we're gonna subscribe.

[00:10:25] So obviously this isn't gonna work right now. Because we don't have a map function. So let's go ahead and write our map function. So you guys are experts at writing observable functions right now. So you're gonna help me out here.
>> Speaker 2: I assume we have to use this thought subscribe?

[00:10:47]
>> Jafar Husain: Right, because the source of the data, right now, clicks as it were is actually the this object. Because map is an instance method on observer. If I use this object here though, I'm gonna run into a problem. What is it?
>> Speaker 2: This binding. We'll be able to find-

[00:11:04]
>> Jafar Husain: This binding problem. This binding because this function is here. But this binding [LAUGH] is gonna be to this observable, and not the exterior observable. So we're use that trick we use in JavaScript, where we go, a lot of you might have seen this before. That allows us to store away whether this object was a second ago, right, previously.

[00:11:25]
>> Speaker 2: Why not just use .bind?
>> Jafar Husain: We can use .bind. Yeah, absolutely.
>> Speaker 2: Also, would an arrow function work for the parameter?
>> Jafar Husain: All three of those would work. The reason why I typically don't use an arrow function is just cuz we got so many functions we're slinging here, I like to give it a name here so we know we're inside of subscribe.

[00:11:43] But absolutely, that would work as well. You know what I'm gonna do, actually guys? I'm going to let you guys take a second to try and write this. I'm gonna put this up here, and I'm gonna let you guys take a stab at it. Just give it a shot.