This course is out of date and does not reflect Frontend Masters current standards. We now recommend you take the JavaScript: The Hard Parts course.

Check out a free preview of the full Advanced JS Fundamentals to jQuery & Pure DOM Scripting course:
The "Exercise 17: Solution" Lesson is part of the full, Advanced JS Fundamentals to jQuery & Pure DOM Scripting course featured in this preview video. Here's what you'd learn in this lesson:

Alexis is back to walk through the solution to exercise 17.

Get Unlimited Access Now

Transcript from the "Exercise 17: Solution" Lesson

[00:00:00]
>> [MUSIC]

[00:00:03]
>> Alexis Abril: Let's talk about the solution to this. So we have our pseudo code, our comments set up, which, again, definitely do this. Any time you're approaching any kind of new problem you've never seen before, write it out, try to verbalize it. Writing these comments out are much more difficult than looking up the syntax.

[00:00:22] But let's check this out. We have our accumulator, we have our array elements. And we need to do something for each element in our collection. So what do you guys think we should do if we want to iterate through each element in our collection?
>> Alexis Abril: Anybody have any thoughts?

[00:00:41]
>> Speaker 2: [INAUDIBLE]
>> Alexis Abril: Well, I mean, how can we iterate through each in our collection?
>> Speaker 2: With each?
>> Alexis Abril: With each, yeah, we have a helper. So we're gonna go through each of something, right? What is that something? Do you guys remember from earlier?
>> Speaker 3: This.
>> Alexis Abril: This, yep, we're gonna get our function.

[00:01:09] This is what we're gonna get back, and then we're gonna do these three things within our callback. So the first thing that we do, now we're inside our collection, we're at the first index, and we have access to one of the elements found in our collection. So the first thing we need to do is get elements within that element that match some selector.

[00:01:32] And we do have an API for this. This is our querySelectorAll. And we know this is available on an individual element. So, we know we can do at least this much, el.querySelectorAll. And this function is gonna take a selector. So, oops, we're gonna pass in our selector there.

[00:01:58] And this is gonna return an array like object with all the dom elements that we found. So we can call this els for short. Whoops, this comment is from our previous comment. Okay, now that we found a bunch of elements nested within our current element, we need to add them to our accumulator array.

[00:02:30] So we could do this a number of ways. We're gonna do the shorthand way we did on one of the prior exercises. We're just gonna say we're gonna hijack our push method from our array. And we're gonna say hey, push with a context of elements all of the els that we found, all the dom elements that we found.

[00:02:57] This is gonna take each one of our found children and push them on to our accumulator.
>> Alexis Abril: Then we need to return dollar elements. Now this is something else we needed to change for this exercise. We needed to modify our constructor, so let's go up here and make sure we handle that.

[00:03:25] Here we go. So right off the bat, we need to say, if selector is a string, do what we've been doing. Otherwise, assume we're getting an array of elements that already exist, and just wrap that up without looking up anything. So let's do this, let's move this really quickly here, and let's write this out.

[00:03:49] If our selector is a string, what's a good way we can check to see if something is a string?
>> Speaker 4: typeof.
>> Alexis Abril: typeof, yeah, we can say if typeof selector ===, and this will just return string, then we're gonna do what we did above. We're gonna do the same thing right there, else, assume we already have this.

[00:04:15] So what I'm gonna do is I'm gonna declare elements up here, whoops, I'm gonna declare elements right there. But I'm not gonna set it to this, only in this case. There we go. So, if we come through, so far without any extra code, this is a more verbose way, or more confusing way to do what we were already doing.

[00:04:42] If you come through, we pass in a string as a selector. It's gonna say, if type of selector string, look up core selector all on this document, return that into elements, and then business as usual. Otherwise,
>> Alexis Abril: Do this, and the code is actually already there. I'm just gonna un-comment it.

[00:05:11] Otherwise, we already have,
>> Alexis Abril: What we were looking for. Does that make sense? This part is a little weird. Again, because we don't have method overloading in JavaScript, ideally, you could have different methods. If this was Java or C#, you could have one method signature that takes a string, another method signature that takes an array.

[00:05:42] And the JVM or whatever machinery behind the scenes would be able to figure out which method you're trying to call based on that API signature. But because JavaScript is weakly typed, we don't know or necessarily care at the time the function is invoked. But in our particular scenario here, we want dollar to accept many different types of inputs and behave differently based on the type of those inputs.

[00:06:08] That was a very long-winded way to say that. Let's check it out really quick in our tests, and we got find is working, so if we go into our Beagles page, let me blow up our console. Let's take a look at the DOM really quick. We should be able to do something like this.

[00:06:36] I wanna find our ul on the page, then I'm gonna use our ul to find any nested list items. And then I just wanna use a helper method, I'm gonna use our text helper method to say, Hello. Whoops, so our find is not returning something. Let's take a look.

[00:07:02] I probably just broke something. Yes, our find is returning undefined.
>> Alexis Abril: All right, let's take a look at what's going on.
>> Alexis Abril: So right off the bat, let's check here. See what we're getting back. See if we're passing what we need to into our constructor.
>> Alexis Abril: So we are passing quite a few things.

[00:07:40] Let's get into our individual tests, we don't see so many consoles. So we're passing four li's, which is nice. So let's take a look at what our constructor is doing,
>> Alexis Abril: All the way up here. And I'm just gonna put a debugger so we can step through it.

[00:08:07]
>> Speaker 2: Looks like it's passing.
>> Alexis Abril: The test is passing, but that might just mean we have a weak test. So let's take a look, let me clear out our old stuff. I'm gonna take a look at elements. Elements is coming in as undefined, let's make sure. What's that?

[00:08:29]
>> Speaker 2: [INAUDIBLE] You should try the console for the accuracy breaking, pretty hard to identify what's not working here.
>> Alexis Abril: I'm with you.
>> Alexis Abril: Okay, so elements is coming through undefined, this is not we're looking for. So our selector coming through should be in an array, and we have ul.

[00:08:58] This is the first one, so we want the second one. Let's go through, here we go. So we have an array coming through. So this should fail cuz this is not gonna be a string. So then go here, elements is going to be our selector array. We're gonna go through, and we're gonna iterate three times.

[00:09:25] That should fail, there we go. And now let's take a look at this, what our object looks like. We have three li's, we're about to have a length property. Each of these li's is one of our dom nodes, that looks good.
>> Alexis Abril: So here,
>> Alexis Abril: That looks good, all right.

[00:10:10]
>> Alexis Abril: It probably is working, I probably just didn't save the page.
>> Alexis Abril: Whoops, play through that. It is working.