Check out a free preview of the full Asynchronous Programming in JavaScript (with Rx.js Observables) course

The "Exercise 32" Lesson is part of the full, Asynchronous Programming in JavaScript (with Rx.js Observables) course featured in this preview video. Here's what you'd learn in this lesson:

In this exercise, you will create a mouse drag event using Observables. To do this, you will retrieve only the mouse down events that occur before the next mouse up event.


Transcript from the "Exercise 32" Lesson

>> [MUSIC]

>> Jafar: So here we're gonna complete our mouseDrag example, and what I'd like us to do is I'd like us to take a little break and have you guys tackle this yourself. This is question 32, right? There's a mental leap that goes on here where we draw a line from the example that we've been learning, from the way we've been thinking about array and make that link now to make the leap to thinking about events the same way.

Right, and so I've showed you the answer up on the board, but I really want you to work through it and try and solve this particular question.
>> Jafar: But when we're done, we should be able to drag this Sprite across the screen. And if you run this example and it doesn't work, make sure to refresh your browser because under the hood, it's actually hooking up an event and if you keep running, it'll just keep hooking up that event.

So make sure to refresh your browser if you run it, it doesn't work and try again. Remember it'll will save your state and everywhere you are. So somebody out there was having trouble getting exercise to work, so it might be a little bug in the exercise here, that's okay we'll switch over and make it work somehow.

Did anybody actually get the Sprite to move? Not yet? Okay, that's not a good sign.
>> Speaker 2: I got it moving.
>> Jafar: You did? Okay, which browser are you on? Im curious.
>> Speaker 2: Firefox.
>> Jafar: Firefox, right?
>> Speaker 2: Put in that catalog and it might fix it for you.
>> Jafar: This one?

>> Speaker 2: Cuz you just added that, right?
>> Jafar: Yeah. See, all right. So let's take a look at this code. What did I do here? Well, for every mouse down, I mapped over all of the sprite container, mouse moves. Now this container that you see right here, this grey container, this is the sprite container.

So why do I listen to the mouse moves on the sprite container instead of on the sprite itself? Does anybody know? Well, because of this case. If I move real quick, my mouse can actually get ahead of the sprite. And so the mouse move won't register on the sprite, it'll only register on the container above.

So that's why we added an event handler to the sprite container. And we listened for mouseup for the same reason on the sprite container. So we map over every mouse down. And so now we've got a collection of mouse that we start with a collection of mouse downs and then for every one of those mouse down event objects, those are the same event objects you would've gotten in an add event listener, we substituted using map for the stream of all the mouse moves until the next mouse up.

How many collections level deep is that? How many levels deep?
>> Jafar: How many levels deep is this? So somebody said two, why is it two? This is the most important thing for you guys to be able to, it's hard, it's the most important thing for you guys be able to do, to be able to visualize how deep the collection you're creating is.

And here's something you'd always go back to if you have problems, always go back to first principles. So I got this, right? That's an array, I understand and array. If I map over this and return this, what pops out?
>> Jafar: Right, because if I map over this and I put in this, I get this.

The whole point is the map function is applied to every item in the collection. And then the result is substituted into the new array.
>> Jafar: So if I apply this function here to 1, what comes out? An array of 1. If I apply this function here to 2, what pops out?

An array of 2. So, if your map function returns another collection, you're gonna end up with a two dimensional collection. Because the income, if the incoming collection is flat, right, which it is, here we can see the incoming collection's flat, if for every single one of these items, we substitute another collection, we have a two dimensional collection.

And so the same thing applies here. Sprite container mouse moves, if we take up the take until, it's very obvious, Spite container mouse moves is an observable. Right, and so if for every event object in the stream of mouse downs we substitute in another observable, we have an observable of observables.

And so, first thing I want to do, just like I use filter previously on videos to limit the videos to only the ones I want, now I'm gonna use takeUntil to limit the mouse moves to only the ones that happen before the next mouse up. But that's still a collection.

For every mouse down click, I still created an observable for every mouse down click there is, so I have a two dimensional collection. So I need to follow it up with concatAll to flatten it. So just like I take this here and apply concAtAll and I get one, two, three, okay.

Does that make sense? So can I shorten this? Yes, cuz whenever I see a map followed by concAtAll, we can always just shorten it, helper function.
>> Jafar: But now we understand, hopefully, how powerful this type of compositional programming can be, right. That's a very little amount of code for something pretty impressive, right?

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now