Check out a free preview of the full Mastering Chrome Developer Tools v2 course:
The "Debugging Solution" Lesson is part of the full, Mastering Chrome Developer Tools v2 course featured in this preview video. Here's what you'd learn in this lesson:

Jon walks through the Debugging Exercise solution.

Get Unlimited Access Now

Transcript from the "Debugging Solution" Lesson

[00:00:00]
>> Jon Kuperman: So let's take a look at that debugging exercise. So yeah, the basic idea here is there's something going wrong, kind of a typical vague bug. So if you hit this button that's supposed to fetch stuff, you will see that nothing happens. So my first step is usually to check the console before I really do anything else.

[00:00:18] Cuz the console is where all your JavaScript errors are gonna get thrown. So we kind of look in here and we see this Uncaught (in promise) TypeError: Cannot read property 'forEach' of undefined. We see what file it's in and we see what function it's being called inside of.

[00:00:32] So kind of the next thing I would do is just click through to the file here. And then you get this kinda great contextual helper. So this saves from its last run, kinda underlines in the red squiggly the line for you. [COUGH] It kinda shows you what's going on here.

[00:00:46] So this here is a little bit vague though, right? It's like can't read 'forEach' of undefined. So what is undefined then, it's images, right? And images comes from in here. So for example, if I set a breakpoint on images there’s a lot of different ways we could go about getting to the bottom of this.

[00:01:00] But when I click again, I can see that we’re here in the error and I can see this little context hint here that images comes through undefined. So just to kind of help myself out, I'll add a watch over here, so I'll add a watch for images. And we can see here, it's undefined.

[00:01:18] And then I'm gonna look at the call stacks, so what's happening here? So it starts off with this fetchImages call, right, this function here. And then it hits this then block. And the then block calls processImages with this data. So it looks pretty good to me. I do see that this is undefined, but let's kinda look inside this data here.

[00:01:36] So I'll add another watch over here for the data. And what I can see is what I'm expecting, right, is an object, to some kind of JSON object. What I'm getting is an actual web response, right, like an HTTP response, which is not what I want. So there's a bunch of different ways we could kind of look this up, like response object, convert response object into JSON or something like that.

[00:01:58] The thing, if you look up anything related to MDN's articles on the fetch API or anything like that. If you get back a response blob, you'll have to call a .JSON on it in order to get it into a JSON format. And so one thing that we can go ahead and do is if I go back to my code over here, this is the same file here.

[00:02:16] I know that the first thing that you have to do when you hit a web response like this is you can pass a then and you get this response, and we'll call it response.json on that. So we hit the API, we convert it into JSON when it's ready, then we try to do something on it.

[00:02:33] So if I go back here, I kinda play through the debugger and I hit the button again, we'll see kinda the same thing going on. Images is undefined. And if I go back to here, though, I can see that instead of data being a readable stream, data is an object, which is what I'm looking for, right?

[00:02:50] So if I were to inspect data, I see here it's this object. So then the question becomes, why is it down here, why is images being passed in as undefined? And this is just it happens to be kind of a typo, right? So if we look in here, we can see that data has a key of images and we're passing in to processImages is data.ImageList, so that's undefined, that's wrong.

[00:03:14] So we can kinda go back to the code again and we can do data.images instead. Another thing we could be doing here, right, is we could be work spacing and then editing the sources. And desyncing them from the dev tools either way. So I'll play it through again and then I'll hit fetch again.

[00:03:31] And so now we're in here, we see these images, we've got the four images. That all looks good. So I'm gonna king of remove this breakpoint and play it through. I still don't see anything. So I go to the console and there's no errors here. So this is where it gets a little bit trickier, right?

[00:03:45] When you have an error, it's nice, it's like a guiding force to help you figure out what's going wrong. But you don't have an error here. So kind of start stepping through here. So we create this list. I wanna make sure that's getting created right. Make all these like items, I might put some, we do some inner text up here, I might check those things.

[00:04:03] Just kinda going through and selecting anything that I'm really interested in, places I wanna stop. So I hit fetch again, and I can see that this create element appears to be working, there's no errors here. So I'll go ahead and step through and I'm gonna hit play so instead of stepping through each line I go to my next breakpoint.

[00:04:23] So I go to my next breakpoint. I'm kind of seeing if these things are right. So I'm going back to my watch and maybe looking at what element it's set to. It's an object, it does have a name and photographer, so those things look right. Setting the image source, again, all this stuff looks right.

[00:04:37] Nothing's undefined or anything like that. So for those that did the exercise, you might notice, though, that we're just not appending anything to the DOM, right? So if we play through and we get all the way down to this list, and then I go ahead and I look at what list is.

[00:04:50] We can see that list is a ul and it's got these children.
>> Jon Kuperman: [SOUND] It's cuz it happened. This is another trick with the debugger. When you stop a breakpoint on a line, it's before that line is finished executing, right? It's not afterwards. So if you have const(foo) equals foo, and then you put a breakpoint on that line.

[00:05:10] And then you try to watch for foo, you'll notice that it's undefined cuz it hasn't been declared yet. Now this is kinda where the debugger line can come in really handy, right? Because what you could do instead of adding this breakpoint, I could remove these.
>> Jon Kuperman: Kinda refresh the page, I could go back here.

[00:05:30] And I could be like, well, I want to see when it's all said and done, right, when all of this is finished. So I can add a debugger line here. And then I can just refresh the page and hit the fetch button and it'll stop here. So now if I go to my list I can see that I have these children.

[00:05:46] They're these cards or whatever. So everything's looking really good there. So kind of the last thing that we forgot to do here is just when it's all finished, append the finished product to the DOM, right? So for each one we make a little thing. So I'll just go here and just something like document.body.appendChild.

[00:06:03] Again, the DOM API's are really not what's important here. It's just important to be able to see is it defined, what am I doing, why is it wrong? So kind of the gist of this code is we do the fetch call, turn it into JSON. Then we take the data and we call a function on its images, which we know is a list.

[00:06:23] Then we create a ul object or element. We forEach through those images and we just start creating these DOM nodes. So we create list items and h2s and spans, some new images, all that stuff. Add some classes, innerText, and then we start kind of building it again. So a lot of people probably use UI frameworks to do this.

[00:06:41] So it's not super vital that you know how to do it with vanilla JavaScript. If you're using react or something like that. But JavaScript does have APIs for creating elements, attaching them to each other, all that kind of stuff. So if I go ahead and refresh the page now and do the fetch Star Wars thing, we'll see that we are getting data, all this stuff is coming through.

[00:07:01] We're still seeing a problem here. So if we go into that undefined, just hit a breakpoint on something, hit fetch. Do another watch, this time we'll do it on an element, right? We'll see that element has, what does it have? Oops, it has two properties. It has name and photographer.

[00:07:18] And we're trying to call element title, which Chrome tells us is undefined. So we'll have to go through here and change that to name. So let's remove that breakpoint, play it through again. Kind of getting these. I think the last thing I did wrong is I switched these, right?

[00:07:33] This is the title and this is the author. So if we wanted to we could do that. So I think it's the title should be element.name and the author should be element.author. Cool, and now we can go ahead and hit that and we got everything. No, we don't, what did I do wrong?

[00:07:49] Still got author.
>> Jon Kuperman: You're so good. That was a test.
>> Jon Kuperman: Thank you. There we go, so now we've got images coming through, no more errors and all that stuff. So kind of the big point of this is just starting to add those breakpoints and see that you get information from a bunch of different places.

[00:08:08] Like you can add a watch for it, or you can hover over it, it gives you that inline context. Start seeing, checking your assumptions, basically. Seeing what's working, what's not working, that kind of thing.