Component-Based Architecture in AngularJS 1.x and ES6 Exercise 6 Solution
This course has been updated! We now recommend you take the Angular 9 Fundamentals course.
Transcript from the "Exercise 6 Solution" Lesson
>> Scott Moss: So, let's start at blogpost.js. So a lot of stuff going on in this file, right? Tons of stuff going on here that we didn't really talk about. And if you don't really know Angular too well, then you're really not gonna know what's going on here, so that was intentional, and I'm sorry.
[00:00:22] But you definitely learned some stuff, guarantee you did. So, the stuff that was here, let's talk about it. So we have the state provider, and the only thing we had different here was, before we talk about the controllers, I have this resolve block. Anybody know what resolve does?
>> Speaker 2: It allows you to create injectables for the controller you're going to use that have to be promises and have to be resolved before the route finishes before you start rendering, right?
>> Scott Moss: Yeah, so, all that's right except for they don't have to be promises. They can be anything.
>> Speaker 2: They can be anything?
>> Scott Moss: They can be anything. You can return anything, but you're right. So, the way resolve works is an object that takes these properties and these properties are strategically named, name is important. So, they are functions that just return a value. And whatever that value is, whether it's a promise or some static synchronous value, that value is going to be attached to this name of this property here and injected into the matching controller on the route.
[00:01:36] So, the behavior is, if it's a promise, the resolved value will be attached. If it fails, then it just won't go to the route. So, either way, this routes right here will not load up until all these resolve functions come back. So, it'll just sit there and wait.
[00:01:57] So, at this directive, we know was not supposed to load up until it had this, that it's guaranteed that that will happen. It will never load up until this happens. So this is good in some cases, not so good in other cases, especially if you have ten things here that are resolving here.
[00:02:15] You're sitting here looking at a blank screen, our loading indicator is kind of not fun. So, there are better ways around that, but that's what resolve is doing. So because of that, that's why I put this note right here that says you need to make a one off controller for resolving.
[00:02:29] Did anybody get that when I said that, like a one off controller, right? Cuz I didn't want you to go like bring the director's controller in here, or to go make another class and put that in here. This is a one off anonymous controller for the specific reason of only taking the post, this post right here is this post, and binding it to either to this or scope, whatever you want, just so that we can put it here.
[00:02:57] That's what's happening. So, let me walk you through it again. So, this controller now belongs to this template, right? And because of that, we can access the scope properties on this controller, through this template. So, we have this post attribute, and we'll talk about that in a minute.
[00:03:13] We can pass in the scope.post here, which is an object. But inside this actual direct, if there's another controller in there that has its own functionality, but we're talking about on the outside right now. Any questions on that?
>> Speaker 3: Steven P is asking a question about why can't we resolve it in its own controller?
>> Scott Moss: Okay, that's a good question. Why can't we resolve it in its own controller? The whole point of resolve is to limit a template from loading up before something happens. So, if we resolve it in the controller, then it's already too late. That means if the controller's loaded up, that means the directive already loaded up.
[00:03:55] So therefore, we really wouldn't be resolving it, already loaded up. I mean, you could hack it. And you can have it to where you have your directive has a dynamic template. Where you say okay, by default, the directive's template is nothing. It's a blank screen, or it's this placeholder or whatever.
[00:04:10] And then I'm gonna go to the server in the controller, come back, then when I come back, now I'm going to recompile your template and your template is now this. So, you could do that. That's kind of hacky, but still, it's not the same as resolve, because resolve actually prevents the URL from changing as well.
[00:04:25] Whereas, the URL will still change, you just wouldn't see anything on the screen, or whatever you wanted to see. So yeah, but if we did it in the other controller, it's already too late.
>> Speaker 3: Cool, thanks.
>> Scott Moss: Any other questions?
>> Scott Moss: Okay, cool. So stateParams creates an object of all the parameters in the URL, so this is a parameter, the title parameter.
[00:04:52] So if I say stateParams.title, I get whatever this value is, all right? So that's why I did this de-structure in here. And then this right here is just getting rid of the dash delimited and putting a space back into it. Because if you look at the blog posts.
>> Scott Moss: But that's not valid URL. So, they're dash delimited on the URL. So, that's what that red x is doing, it's getting rid of those dashes, converting it back to spaces. So, I can find them inside the collection a lot easier. Something you would normally do on the backend.
[00:05:31] But we don't really have a backend so I did it here. And then I'm just gonna say return Posts.getOne. So, all this is already here for you. Posts.getOne, we made this method on the last one. So, it's just getting one post. Which will either look in the array if it's there, or go to the server and get it if it's not.
>> Scott Moss: And then of course, to register our blog post directive. I think that might have already been there, too. I'm not sure.
>> Scott Moss: Any questions on this file? All right, let's go to BlogPostDirective. So, a little bit of new stuff here too, probably had to do some reading up if you didn't know Angular too well.
[00:06:14] Cuz a feature that you would need in here was actually recently released. So, had to do some reading on that if you didn't know. But so, basically, this is just a regular directive that we've always had. The template, the style and the controller, nothing new there. The only thing new that's worth mentioning is we actually put something on the scope here, right?
[00:06:32] So, how you knew this was, actually, was here for your already?
>> Speaker 4: Yeah, it was.
>> Scott Moss: Okay, okay, never mind. So I'll talk about it anyways. So, the reason this is here is so that we can pass in data into our component, right? So, we define, whatever we put on the scope is gonna be an attribute that we can use on the directive.
[00:06:48] That's how we can use this post attribute here, because we said so in the scope. And then, why is it doing that? And then because we said its value is this equal sign here, that means we're gonna pass in some type of object or whatever, and it's gonna be two way data binding.
[00:07:08] So, if we change the value of that passing object in the directive, it's also gonna change on the outside. If we change it on the outside, it's also gonna change inside the directive. It's two way data binding. That's what that equal sign means. If we did a at sign, that means we are just gonna pass in one way data binding.
[00:07:25] So if it changes on the outside, it'll change on the inside, but not the other way around. All right, it's usually for primitives, so if you're passing a number or a string, but it's also a better way to do that, too. And then the other one is ampersand.
[00:07:40] This is like I want to pass in a function. So I want posts to be a function that's on a controller somewhere else. This one's kind of confusing to use, I literally avoid it at all times. So, it's usually this or nothing else for me, even if it's a static, there's another way to get static properties than using the at sign.
[00:08:01] You can just use the add or attributes. Cool, so the one that you might have to do was bind to controller. So, does anybody know what that is?
>> Speaker 4: It's the thing that binds that scope to the controller you specify.
>> Scott Moss: Exactly, so it'll take whatever properties are on the scope definition and bind it to the controller.
[00:08:23] So now it's under our control, we can say this.post. That's what is that does. This feature just came out like 1.3, if we didn't have this, it's kind of hacky to get it to work, cuz the controller actually runs before the link function, because the scope, you get access to the scope here.
[00:08:40] This is where you get access to the scope and the link function. So, you say scope, but by the time this runs, the controller would have already ran, so you'd have to do some hacky stuff to get it to work.
>> Speaker 5: You can inject the scope though in the controller, right?
>> Scott Moss: Yeah, you inject the scope into the controller.
>> Speaker 5: I'm just deciding
>> Scott Moss: Yeah, but it might not be anything until that runs. You know what I mean? You could inject it, but it might not be anything, right? You don't know.
>> Scott Moss: Because the linking, that's why it's called a link function, as that's the linking phase of the directive, so our other control ran around already.
[00:09:20] The linking of the scope variables has it, right? So, it'll just be nothing.
>> Scott Moss: Any questions on this one?
>> Scott Moss: Okay, and then off to the controller, which is nothing. There's nothing there, really. I don't think this controller does anything. If you did some fancy stuff in here, that's cool, you should share, but I couldn't think of anything to do with the blog.
[00:09:45] I mean, I could've made a side widget and you can share to Facebook or something, but I didn't feel like doing all that. So yeah, nothing here, but it's nice just to have it just in case we want to add some stuff. And then of course, this will not work if we didn't go on app.js and register our blog post.
[00:10:01] Blog post.name.
>> Scott Moss: All right, okay, so, again, if we have all this working, we should see this. All right, so everybody has this? Is everybody checked out to the solution bridge? [LAUGH]
>> Speaker 2: [LAUGH]
>> Scott Moss: Yeah, we all got it. Cool, any questions on this before I move on to what's next?
[00:10:31] Okay, so if you thought this one was hard, it's definitely going to get harder. [LAUGH] So, let's go back to the notes. So we'll do a little bit of recap here about what we've been talking about because-
>> Speaker 3: Hey Scott, before we move on, there was a question on the test set up that you have for this exercise.
>> Scott Moss: The test set up?
>> Speaker 3: Yeah, so the spec.js that we have for blog post.
>> Scott Moss: Okay, yeah.
>> Speaker 3: Let me see here. P was wondering why we need to import the styles?
>> Scott Moss: In the tests?
>> Speaker 3: Yeah.
>> Scott Moss: I don't have tests for this one. If he has tests on his, not sure.
>> Speaker 3: Blogpost.spec.js. No, yeah, you didn't have anything in there.
>> Scott Moss: Yeah, I don't have any tests.
>> Speaker 3: That was for us to do, so maybe he was referring to blog.spec.js that we got yesterday.
>> Scott Moss: Blog.spec.js.
>> Speaker 3: Also has an importing the styles.
>> Scott Moss: No, it's not gonna import.
[00:11:34] So it imports the directive, which indirectly imports the styles.
>> Speaker 3: I see.
>> Scott Moss: Yeah, so you don't need the style. I mean, if you wanted to run test against CSS, you could. Theoretically, you could import the style as a raw text and run that through a RegX to see if they change anything.
[00:11:51] If you really want to get crazy, you can totally do that. But yeah, there's no need to import the style here.