Check out a free preview of the full Advanced Asynchronous JavaScript course

The "Debugging 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:

With an early version of the image viewer application not working, Jafar uses the moment to introduce the concept of how to debug observables. Next, Jafar continues to debug and build out the application focusing on indices, trying to pull the first value of out an array.


Transcript from the "Debugging Observables" Lesson

>> Jafar Husain: I'm gonna comment out our consumption code.
>> Jafar Husain: Uh-oh, file not found. Not sure why that is but, hmm. That seems kinda suspect, right? Probably made a mistake somewhere if I see that.
>> Jafar Husain: Let's see.
>> Jafar Husain: Indices map.
>> Jafar Husain: I think something's off about this.
>> Jafar Husain: So, I wanted to do this in class, so that we could also go over debugging, right?

Debugging's always an important topic when we're doing these things. How do you debug an observable? Anybody have any ideas?
>> Student1: Do?
>> Jafar Husain: Do, excellent, all right, we got a ringer here. Yes, do, that is how you debug an observable. What do essentially allows you to do is perform some side effect whenever an item is admitted from a stream.

And a good side effect is sometimes just, either logging to the console, but my personal favorite is actually just throwing a debug or semicolon statement in there. So, a lot of people think, you can't debug observables, but it's not true. You can actually put a debugger semicolon statement inside of any function, your map function, etc and sort of get a read on what's going on.

So, the first thing I'd like to know is, I'm pretty confident this is an images array, cuz we tested that before, right? I'm wondering what's going on in here. If there is even anything going on in here.
>> Student2: I see-
>> Jafar Husain: Yeah?
>> Student2: I think it's an es6 problem.

>> Student2: Did you have the brackets there before?
>> Jafar Husain: I just put them in.
>> Student2: Okay nevermind.
>> Jafar Husain: So this is, by the way, when you want to debug, you take the arrow function and you put brackets in here so that you can put statements inside. And then you put a debugger semicolon, does that make sense, everybody?

And I also put a debugger in here just so I see what's going on. And now let's rerun this. Okay, interesting, notice we didn't hit this right here. Hmm, wonder what's up with that. It wants the URL at least? Look, it's an observable. Well, that's not gonna work.

So, it looks like we actually have a two-dimensional observable still. I'm not entirely sure why, but that's usually what that indicates, right? If we get on next in an observable, it means we haven't done enough flattening. So maybe I was wrong. Maybe we have a three-dimensional observable or something.

So, let's see if we can get to the bottom of that. All right, so, the url is indeed an observable.
>> Jafar Husain: Right, so earlier we thought we're just mapping over this observable, right? They must still be flat. But it's not, right? If I do this,
>> Jafar Husain: Right? I'm still mapping over that observable, but the problem is I'm returning another observable for every item in the observable, which means I get an extra level of dimensionality.

And in here, what are we doing? For every images array we're returning an observable, right? We're taking this indices and we're mapping over it. So, we actually ended up with a three-dimensional observable. Mind blown, right? Well the reality is, deeply nested observables are actually not so hard because generally speaking, as you go, you're flattening them, right?

Every time you get into a new level of dimensionality, you say, how would I flatten this thing? And then you pick one of the three flattening strategies. Until finally you go from how ever many levels deep to one. S,o let's put this down here.
>> Jafar Husain: I like the shorter form myself.

>> Jafar Husain: Okay, so, it seems like we still have a two-dimensional observable. But how are we gonna flatten this level right here?
>> Student2: We could use a merge map there, sort of map.
>> Jafar Husain: Yeah, sure, all right, no need to be creative here. That would definitely flatten it. Is it the right flat?

>> Jafar Husain: So, every single time we get a new array of images, right, we're gonna create this stream of images, right? But what happens when a new sub is selected? Right? What we're really trying to decide here is, actually, let's take a step back here. Before we focus on this inner two-dimensional observable, let's focus on the outer one.

So, every single time a new sub is selected, we're going to go and get the SubImages for that sub, right. We'll create another observable right here. But what happens if a new sub is immediately selected, while we're still loading the data for the previous sub?
>> Jafar Husain: What do we wanna do?

Do we wanna merge all?
>> Student3: You're gonna wanna switch [CROSSTALK]
>> Jafar Husain: You might wanna switch latest, right? Cuz I don't care about the data from the old sub. So, instead of merge all, switchLatest. Okay, so with that in mind now let's talk about the inner one, right? Once I get images, I'm immediately gonna return unobservable, and as you move left and right, right?

We're gonna return new images URLs For the corresponding index in that array. What's the flattening strategy I wanna use here?
>> Student2: Switch latest?
>> Jafar Husain: Switch latest? Honestly, it doesn't really much matter in this particular case because getSubImages is only an observable of one. Does that make sense? Because it's only an observable one, it really doesn't matter what flattening pattern we use in this context.

So, given that, the cheapest one, it's actually roughly the cheapest one, is to use switchLatest. Does that make sense? Is that clear to everybody? If you have an observable of one, right, it's not gonna make any difference. We're always gonna return this indices observable. So,
>> Jafar Husain: Are we done?

Maybe we can at least try it, right? I think we might actually get something going here if we tried this one.
>> Jafar Husain: Maybe not, it's angry about switchLatest.
>> Jafar Husain: Why is it angry?
>> Jafar Husain: Usually it displays the error there, switchLatest is not a function. I'm guessing I made some sort of mistake here, cuz switchLatest is definitely a function on an observable, which is what gets returned for map.

This dot shouldn't be here. Right? Or should it? [LAUGH] Any eagle eyes out there spot what I did wrong? That dot should be there, cuz that's hw you can switchLatest here. I feel like I've done something wrong.
>> Jafar Husain: I got a return missing.
>> Student4: You're missing a parentheses on line 70?

>> Jafar Husain: I think I would've gotten a syntax error, but you said which one? Line 70?
>> Student4: It might just be my error.
>> Jafar Husain: It's always good to try and reduce these things a little bit.
>> Jafar Husain: All the parentheses look lined up.
>> Jafar Husain: It's probably that, though, I've probably got something off if I've got an error where it says there is no switchLatest method, hmm,

>> Jafar Husain: Sync the map looks all good to me, actually. One of these returning a switchLatest. I'll try that one more time.
>> Jafar Husain: So we can still debug these things, of course. I'm gonna see what actually comes back from this. An observable
>> Jafar Husain: And do I actually have a switchLatest or a map or anything like that?

>> Jafar Husain: Maybe brackets around the whole thing.
>> Jafar Husain: Doesn't Chrome usually autocomplete here for me? That's a little bit odd, right? Why don't we try a little assignment?
>> Student5: Got two minutes.
>> Jafar Husain: [LAUGH] Thanks, guys.
>> Jafar Husain: Oops, my bad.
>> Jafar Husain: Okay.
>> Jafar Husain: Hmm. [LAUGH] new RX it's been renamed.

It's not switchLatest, I think it's switch. At least that's what I think's going on, so sorry about that.
>> Jafar Husain: Let's give that a shot.
>> Jafar Husain: Okay, not quite where we wanna be, I don't see any images. Why don't I see images, actually? We kind of expect that we're gonna get zero first, right?

But actually, that's not the way that scan works. Scan doesn't emit the accumulator first.
>> Jafar Husain: So, if you give it an initial value, it doesn't emit it. We want indices to be not just the changes. Much like sub, we don't want just the changes, we want some initial value and then all of the changes.

And so because scan doesn't initially emit zero, how can we make sure that zero leaps out of indices whenever we subscribe to it as the first value?
>> Student2: We can concatenate it with zero?
>> Jafar Husain: Yes, we can concatenate it on to the front.
>> Jafar Husain: There's actually shorter forms of this, like starts with and things like that, but I'll just keep it like this for now.

>> Jafar Husain: So, I think that was our problem, that we were subscribing to the observable but it hadn't fired. And therefore, we don't pull the first value out of the array.
>> Jafar Husain: So let's try this time, come on. Already getting somewhere.

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