This course has been updated! We now recommend you take the Deep JavaScript Foundations, v3 course.

Check out a free preview of the full Deep JavaScript Foundations course:
The "Challenge 8: Solution" Lesson is part of the full, Deep JavaScript Foundations course featured in this preview video. Here's what you'd learn in this lesson:

Kyle walks through the solution to Challenge 8 and answers students' questions.

Get Unlimited Access Now

Transcript from the "Challenge 8: Solution" Lesson

>> Kyle: So let's talk about the solution to this exercise 8 and then wrap up. As you can see in the read me, gave you some precise instructions. We wanna remove the setup UI function and instead, using object.create define a UI object that delegates to helpers. So if we were before calling setup UI and making a public API, now what we want to do is make a UI object.

[00:00:26] So on line 39m I'm making a UI object which delegates two helpers as you see there on line 39, we delegate two helpers and we copy this stuff into that object so this literally lets me use the literal syntax to copy it in. And I've got my project template and work entry template as properties on that object as supposed to hidden internal variables.

[00:00:48] And then I just start listing out my functions like my init method, my submitNewWorkEntry method. All same functions I didn't have to change much about how those worked, I just changed what they are being added to, so another being added to this object. The readme also tells us to do the same kind of change to [COUGH] make the application object, instead of setupApp, we wanna make the application object.

[00:01:15] So if I scroll here, we had setupApp, which took in the UI and it made this instance of a public API. Let's make an application object to do the same. So I'm still gonna have the setupApp function but I need an application object that delegates to that UI object that we created above.

[00:01:38] An application object has the following methods in it.
>> Kyle: All that code should be basically the same. We still have setup project, and we have a project object now, instead of adding stuff to some project up prototype, or whatever, we have an OLOO style object for projects and those methods.

[00:02:04] And my setupProject creates an instance, if you will, that links to project. It adds the properties to it that it needs and it gives us this instance bag. So it's kind of serving the purpose of a constructor function here. So there's our four separate objects. We have the helpers object, we have the UI object, we have the application object, and we have the project object.

[00:02:33] Those are the four objects. They're all gonna be in a prototype chain together. So what are some of the differences in code? Do we have to change much about the code to make that work? Well, there's one key difference in terms of how we deal with stuff. You'll notice that in the previous example, when we instantiated, or when we called our things, we made a UI object and called UI.init.

[00:02:57] That's the way the original exercise was, and then made an app where we pass it in. In the fixed version, that looks a little bit different. In the fixed version, we've already got the UI object so we don't need to make it. And we call App.init. Now if you look at the code, there is no App.init.

[00:03:17] Init is in UI, which is higher up the delegation chain. But why do we call App.init? Well, the reason why is that when call App.init, that's gonna delegate to application. Remember, app is that object which is then delegating to application. Application doesn't have an init, so application delegates to UI, and UI does have an init.

[00:03:45] But when we call than init function, what's this keyword going to be? Still gonna be App. So all of these properties, instead of being added to the UI object, they're all gonna be added to the application object. And you'll notice what I did right here when I set up the click handler.

[00:04:04] I said call submitnNewWorkEntry but make sure we call it in the same context. So when submitNewWorkEntry is called, what is this keyword gonna be? Still gonna be App, right? So we carry forward that app context throughout all of these calls. The methods are all on their different individual objects, but it's the call site time when all of them virtually compose.

[00:04:33] So just as an example, when I call this stop validate entry, does app have a validate entry? No, what about application? Does it have a validate entry? No, what about UI, does it have a validate entry? No, but where does UI delegate? Helpers. And helpers does have a validate work entry.

[00:04:58] And when we call this.minWorkDescriptionLength, where are we gonna be getting that? We're gonna be getting those properties directly from our app object, okay?
>> Kyle: So the point is that we were able to create four separate objects, put data by virtue of our call site binding, put data on one of them and leave the methods on the four separate ones.

[00:05:27] And those methods are all able, even in the circular relationship, they're all able to virtually compose and call each other. And all the method calls, they all just say, this dot in front of them. Pick another one, right here, this.addProjectsToList. It's all one context, so it doesn't matter where it comes from.

[00:05:48] The delegation will take care of that dispatch.
>> Kyle: I regularly get asked, can you give me any kind of scaled example of using a OLOO? This is a scaled example. I mean, it's not a million line application. But it's a couple hundred lines of code, and some decent amount of complexity to logic.

[00:06:12] And it shows you that can, at scale, use OLOO to delegate between your objects. Now, as a word of caution, just because that's what I've done here, that does not necessarily mean that I go and use OLOO everywhere. As a matter of fact, I probably use the module pattern like 90, 95% of the time.

[00:06:31] Because most of the time, the module pattern is more than sufficient. But every once in a while, I run into a scenario like this one where I've got multiple different objects that need to refer to each other. They need to cooperate to get the work done. And as soon as I run into a problem where I've got different objects that would basically circularly call each other, like these were, I think to myself, instead of making circular references, why don't I make a virtual composition?

[00:07:00] Cuz that's what delegation is good at