Transcript from the "Task #3 - Header Module" Lesson
>> Kyle Simpson: Now task 3. Now that we've done some stuff with jQuery, we've gotten some things loaded up. Task 3 then what we want to turn our attention to is not adding new functionality to the app but reorganizing the way the existing functionality is. So, if up to this point, you felt like, you're a little bit overwhelmed with the jQuery stuff or maybe your stuff is not working.
[00:00:26] I want to remind you that my best suggestion is for you to grab the contents of task two and just overwrite your files with all the contents of task two. So that you're in a clean fresh environment cuz for task 3, I really do think this perhaps one of the most important parts of all the exercises that we've done.
[00:00:45] Is to get our heads around how to use organization techniques like the module pattern to arrange our code. So the first task here shows us that we have it tells us to open up these three files and we want to use the module pattern to expose a module for each one of those files.
[00:01:05] So I'm gonna do the first file, and then I'm going to leave you maybe ten minutes or so, for you to work on the second and the third files. And you'll do exactly the same thing, so it'll be the same pattern. But I'll show you how to do the first one, and then I'll let you.
[00:01:22] So [COUGH] let's work on the header. I'll open up back up header.js. And I'll do header, and then you can do the carousel and the details ones, okay? Again, we're not gonna add any new functionality. We're just gonna reorganize this functionality. So the observation that we can make about header.js Is that all of the stuff that we see here is happening out in the global scope.
[00:01:49] There's a document ready that's happening in the global scope. If the document ready wasn't there. This variable would be a global variable. That's the sort of code smell that we want to try to avoid because there's no organization around this at all. It's just in its own separate file but beyond that there's no nice clean interface for it will could have accidental overlap with other functions and variables and things like that.
[00:02:12] So we typically wanna avoid as much as possible any kind of stuff happening out in the global scope which is one of the really best benefits of the module pattern is how easy you'll see in just a moment. How easy it is for us to take what we would call just sort of global blah spaghetti code and reform it into something that's more well defined.
[00:02:34] That's really the main point of the module pattern. So I'm going to do this file and then you take over and do the other two. Okay the first thing that we want [COUGH] is we're gonna want a thing to represent our module, a variable. So I'm gonna call mine capital H, Header.
[00:02:51] Now I'm going to wrap a function around all the contents of what's happening here as my first step. And the interesting thing about doing that though Is that I've wrapped the function around it but, that function has not run yet. Okay, It's just a function that's wrapped. But, if we want that function to execute.
[00:03:16] We actually need to execute that function expression. Which the most common way of doing that, we didn't go over this explicitly it's covered in the book. Is to put a set of parentheses around that and then another parentheses set on the end. That final parentheses set down there is the most critical part cuz that actually executes our function.
[00:04:01] So we call it the IIFE. Okay? So I got an IIFE function that wraps around and runs stuff. Now inside of it, I don't want this document ready stuff here. So I'm gonna take temporarily I'm gonna take the document ready part, and I'm gonna move it outside of my module and we'll come back to that in a minute, okay?
[00:04:22] So I'll take that one and that one, put those down here. We'll come back to those in a little bit. Now this code if we try to define what is this code doing it's essentially the initialization code for our header module right. So we could take function init.
[00:04:47] Call it init and wrap a function declaration around all of that code.
>> Kyle Simpson: Did everybody follow that?
>> Kyle Simpson: And then we could observe that we've got an inline function here. Which isn't really buying anything it's actually more complex to look at the code that way. So I'm gonna take that function and not make it be a callback expression.
[00:05:14] I'm gonna move it out and have it be its own separate function, which I might call headerLinkClicks, just making up names at this point. Okay, so, that code I'll put in here.
>> Kyle Simpson: So this is my init function. And I need to call, what I'd call that function, headerLinkClicks?
[00:05:57] That's the name I need to pass for my callback.
>> Kyle Simpson: Now this modal variable, you can see it's being declared inside of init, but it's now being used in a different function and everybody see why that would be a problem? It's being used inside of the headerLinkClicks function but it's only been declared inside of a init.
[00:06:24] There's a simple fix. Take the var part out and instead, make it something that's available to all the functions here by making it a module level variable decoration. Still assign it inside of here, but now when I declare it there now it's available to all of my inner functions.
>> Kyle Simpson: Questions on that, do you see that how that works, how that part works? Now the last step is that this module needs a public API right. So I need to do a return statement with an object. And what do I need to put on my public API?
[00:07:25] I need to put a reference to that init function.
>> Kyle Simpson: Does that look familiar from the stuff that we did about an hour or two ago we did earlier this afternoon after the lunch break? We have inner stuff, these inner functions and inner variables and here Is where we declare our public API.
>> Kyle Simpson: So, the thing I want you to get, and I'm gonna again use the trick of code folding to make this more visible to you. I'm gonna take that internal code just temporarily. I'm going to code fold it. So you don't have to look at it and what I want you to see here is that header is now going to reference that object that we returned.
[00:08:19] Does everybody see that part? That object that we return gets assigned to a variable called header which means on the outside. What can we do? We can call header.init, right, which is what we wanna pass the document.ready. We just wanna pass a reference to the header.init function.
>> Kyle Simpson: Remember I'm not calling init, so I'm not putting the parentheses here.
[00:08:47] I'm just passing a reference to the function so that jQuery will run it later.
>> Kyle Simpson: Kevin is asking a question versus the other way shown earlier can you be more clear on what other way you're talking about. Okay. If I save this file which I will and I rerun my program, I just refresh my page and verify that my register link still works correctly.
[00:09:35] And my login link still works correctly. That means I didn't change any of my functionality. All I did was improve the style of my code. Lets make some observations about the style of my code. These functions no longer have any potential to be public. These functions are now hidden privately.
[00:09:57] And the only thing that gets exposed is this function, the init function. We exposed that publicly, but the var modal variable it's not exposed publicly. It's hidden as a detail inside of the module.
>> Kyle Simpson: So the question in the chat room is, [COUGH] in an earlier version today, you might remember that I just did something like,
>> Kyle Simpson: Function Header, or we called it function hello earlier. And instead of having that stuff down at the bottom, it's just a normal function. And you might remember that I did something like o = Hello() from earlier. So what I'm doing is combining those two things into one step, instead of declaring a function and then calling it once.
[00:10:53] If I only need one of it, it's basically a singleton. If I only need one of it, I'm just combining those two steps instead of declaring one and then calling it. I'm using the IIFE to declare and call it all in one step.