This course has been updated! We now recommend you take the Angular 9 Fundamentals course.
Transcript from the "Angular Building Blocks" Lesson
[00:00:00]
>> Lucas: So when I did my first Angular GS workshop I did a variation of this graphic because, if you can believe it, Angular GS was super confusing. And so I just scaled it down to this graphic of like here's the big picture. It's only eight pieces. This is what you have to know, eight pieces, which at the time was only eight pieces.
[00:00:23] This is way easier than I thought, but fortunately for us that it's gotten even simpler. That there is really four main pieces in angular. There are some kind of little edge cases here but for the most of your work, I would say 90% of the time you would do this 100% of the time.
[00:00:49] It's your modules, your routes, components, and services, four pieces. And today we're really gonna focus on the component. But we'll also touch on routes and services.
>> Lucas: So let's talk about the module.
>> Lucas: So this is a slightly overloaded term. Because Angular provides module support at the language level and the framework level.
[00:01:19] So this happened in RC5 that they introduced module. And this is so we could do ahead of time compilation and lazy loading some different things. But first and foremost that we use ES6 module to provide organization at a language level. So all this really does is it creates a container that says I need these things and I'm making available this thing to the rest of the world.
[00:01:47] So pretty simple, we are exporting Items Component but, we're also importing these pieces here. So I just think of it as a box that says, this thing is going out, but I also need these things to work.
>> Lucas: Now, Angular uses @NgModule to provide organization at a framework level.
[00:02:14] And so at a language level, we use that to compile our application in a way that makes sense, but we use NgModule to tell angular itself, this is how this application fits together. So this allows us to communicate certain things, such as what view classes are we using.
[00:02:34] What other modules do we need? Do we have additional services, so providers just think this is services? And if it's a top-level module, what is the entry point. And so bootstrap will tell it start with this module and bootstrap your application and so here is a pretty standard NgModules.
[00:02:55] So first and foremost we're saying here's our components or something that's going to show up in the View so our view declarations. Our imports, so these are submodules. At this moment have an ItemsService. And we're going to bootstrap with the AppComponent. And so this is just a manifest if you will, that's saying this is how this Angular app is going to be put together, but, it's just really, I would say a map or a manifest saying this is how this thing is organized.
[00:03:32] Now one other thing to point out is that before you actually bootstrap to a component, but now you bootstrap to a module. So we're saying over here bootstrapModule(AppModule) and then from there when AppModule gets bootstrapped. Then, it'll look and say okay, well, what component do we start at?
[00:03:58] And that's where over here, we're saying start with the app component. One other thing worth pointing out is you'll notice that we're using platform browser dynamic to bootstrap the application. Well, angular being a platform. You can target a lot of different build destinations if you will. So for instance, it can be electron.
[00:04:22] It can be server side. It can be with web workers. Ahead of time compilation. There's a bunch of different ways to actually compile the application. This is the most basic one in other words just run it in the browser and run as a dynamic web application. But we have the ability to control how the application is even span up, which is really really interesting.
[00:04:44] So if modules are kind of the big container. So think of that as if somebody asked Mark Mark, where do you live? He might say, well, I live in the Twin Cities. And so that might be a module, so it's a very large container that houses a single cohesive thing.
[00:05:04] But within that we have major highways, and this is where routes come in. This is pretty much just a way to navigate to a specific component within your application. So generally what in it's simplest form, it just contains a path, reference and a component reference. And then in the URL, when there is a match, then Angular would say, okay, here's the path, we've matched it up Let's take this component and let's just load it into the router outlet.
[00:05:35] And so this is a way to have a single page that's loading multiple components into the page, depending on the url. So you can think of the url as kind of a serialized state of the applications. So, for instance, if you're /users, well you're wanting to see that state or if you have four slash items or widgets, well you want to see that state of the application.
[00:05:57] Even if you wanted to do route params, you could be like users forward slash one. Well then, the router is going to serialize that and say, we need to actually see the user with the ID of one and load and handle that accordingly. And so it's loaded into the router outlet component.
[00:06:16] And then we navigate using the rod of interactive. So this is just a convenient directive that saves us a lot of typing in terms of, we don't have to hand build like our anchor tags. Router link built to the users. And just so it knows, it'll load it up for you.
[00:06:35] So just a really handy thing. Now, one thing worth pointing out is that Router uses history-pushState. So you don't have these hash tag users hash tag, item hash tag widget. It's that it's used in history-pushState. And so you have to set a base-ref tag in your index.html. So the Angular sail light does this for you.
[00:07:00] Where I've had to modify this is if I'm running in an electron app. Then the paradigm of being in a browser, it shifts a little bit. As well as I've seen applications that need to run on a subdirectory of the root domain. So it might be something.com/demo and then you actually have the apps.
[00:07:21] So you will need to adjust your base ref so that it doesn't basically just wash that out, it ruined kind of your URL kind of references. And so here path component, really simple here. Path items, component, ItemsComponent. So it's just simply saying when you go to for slash path take or for slash items, that's the path.
[00:07:52] Load the ItemsComponent into the router outlet. So pretty simple. Yes?
>> Speaker 2: A question about injecting dependencies like Bootstrap and stuff to a route or Add an application layer. So, the bootstrap JavaScript library, where would you, cuz I'm assuming we're using it later in the-
>> Lucas: Yeah, so the question is, would we be using Bootstrap 3 or 4 in the sample application?
[00:08:22] The answer is no, because we are using Angular Material. The difference is that, because we're using Angular Material, we have actual Angular components that adhere to the standard. Now there are Bootstrap components, so there's libraries where they've actually taken the Bootstrap styling, the different things, and wrap those in Angular components.
[00:08:48] And you would simply import that as a submodule. So let me ask you to pull it up in the app and I'll show you where that would go. But if you're just using the CSS, then you would just actually just put that into your index.html or you could bundle it.
[00:09:04] But that would just be purely a styling thing. We're using any material, because we actually get fully functional components with it, but-
>> Speaker 2: If you has JavaScript with it.
>> Lucas: Yeah, it's functioning you know JavaScript living breathing things that we're actually finding to our page. With that said the segues into kind of a nice sub topic that I think is interesting.
[00:09:30] So, remember I said a module is basically a container that consumes things and exports things. Well, what they've done with Angular Material is they want you to be able to consume these components al a carte. So if you have a 50 component library and you need two of them, well, then it wouldn't make sense, from a performance standpoint, to have to import everything, consume it all.
[00:09:58] So they let you consume just the thing that you want. What I've done is I've created an app material module. All this is is just a container where I import all of the separate modules that I'm using and then I'm exporting it into a kind of single place.
[00:10:19] And what this allows me to do is now because I'm exporting, it's available to ever consumes this top level rapper module. Down here, I'm just importing the app material module. And because I'm exporting all of these modules I'm not having to go and import these one by one over here.
[00:10:45] Is I've just created a top level module that can pull them all in. And then I'm exporting them as a single collection. That I can import here. So the question is. If there was a bootstrap library, and I'm certain there is, we would import that module. So it would look something like, and this is completely sudo code.
[00:11:11] With import { BootstrapModule } from,
>> Lucas: I'm totally making this up, and so we'd import it. And so this is modules at the language level. So we're simply saying, we need to pull this in as we compile it altogether and bundle it, but then we also need to make this available to the application.
[00:11:41] And so you would put it in here and import it, at which point if this quasi Bootstrap library that I just imported if it truly existed, I would then be able to use that in the rest of the application. So the shape is the same, we're just using a new material.
[00:11:58] Routes, we're trying to ask specific questions instead of like, does this make sense? Does anybody have any questions? Does the shape of, I want to go to a specific state in the application, so mapping a url to a component being loaded into a page. Does that make sense?
[00:12:21] So now, the atomic building block of Angular is components. Now the component under the hood consists of two things, template and a class. So a component class and I will try to refer to it as a component class but if for some reason, I say controller, that's my 1.x habits shining through, surfacing.
[00:12:55] I mean the same thing, because it essentially controls the component as a whole. But components, Component Classes. They're just ES6 classes. And then properties and methods Of the component class are available to the template. And providers, services, dependencies, they are injected in the constructor. So I am a huge fan of dependency injection.
[00:13:28] Because what this allows you to do is when you have a dependency and you need to test it, instead of injecting the real thing you can simply inject a mock. And so being able to decouple your application and then wire it back together with a pendency injection, I think is really, really, really, really important.
[00:13:51] We use dependency injection in as parameters into the construction. So I'll talk about that a bit more in a moment. But just know if you have an items component that needs an items service. That's going to be a parameter in the constructor. Also, especially in JavaScript, in the browser, that things are asynchronous.
[00:14:16] Things happen, components get added to the stage, they get taken off, things change. And so, internally, there's this secret lifecycle of components. My friend Leo did a really good talk riffing on the Secret Life of Pets is that things are happening whether we know it or not. We have on a knit.
[00:14:38] Something's taking off the stage. You have on destroy. The Angular team exposes those lifecycle hooks. So that we can tap into them and do some really powerful things. Namely, clean up after ourselves as a component is being taken off the stage. Huge high-five to them, because they actually push that back to Angular 1.5 and up.
[00:15:00] So you can actually use component life cycle hooks in 1.x and I recommend doing that.
>> Lucas: So this is a component class. Who here has done C# and/or Java?
>> Lucas: So some of this should look pretty familiar if you come from a classical language. That we have a class and it's called Item Component.
[00:15:33] And we're just implementing an interface. And so what we're saying is this is a contract that we have to honor, which in this case is a life cycle hook, which is ngOnInit. So we do not explicitly called the method. It implicitly gets called for us when the component has been added to the stage and its bindings have been satisfied.
[00:15:57] And then you can see here, items, selected item. Property on our class. We can now bind to it. And if we add another method down here, we could technically call ngOnInit. I don't recommend it but if we had another method in here, we could bind to it and call it from our template.
[00:16:14] And they can see here we have a dependency of item service. Well, we're injecting it into the constructor. So, if for some reason everybody here forgot how to program. And I was starting with a blank slate, just programming in general. A class is a container, you have properties and methods.
[00:16:37] Like, if I just grossly simplified what I do every day, is properties and methods. If you have a property on your class, you can bind to it. If you have a method on your class, you can bind to it as well.
>> Lucas: And so, on the flip side, if the component class is the brains, then the template is the beauty.
[00:17:03] So maybe Beauty and the Beast would have been a better joke had I thought about that a little harder. Templates, they're just HTML. And they tell Angular how to render a component. Now, if you've done 1.x and you go to the documentation or if you've never done 1.x and you still wanna go to the documentation.
[00:17:23] They have all these built in tags essentially, and attributes that you can put into your HTML. For every event, it's click, submit, mouse over, swipe left, swipe right. I mean, it's just on and on and on and on. Angular, going back to this standards approach, they decided, look, we're not gonna create one for every single DOM event.
[00:17:47] Like, we're just going to leverage the native DOM events and properties. And so our binding syntax is expanded slightly, but now we're just leveraging the DOM to fire our events, which is really, really nice. So there's a click event. You combine to it. And so, if you go for instance to the MDN, I haven't tested all of these.
[00:18:07] So, there may be these weird edge cases. But pretty much, if it's a DOM event, you can just bind to it. Just pick that event, wrap it in the syntax, and you can capture. Pretty awesome. One other thing, I'm not gonna get really into this, but what does CSS stand for?
[00:18:31] I'm looking at.
>> Speaker 2: Cascading style sheet.
>> Lucas: Yes, and the problem with CSS is that it cascades. And that's a real problem, especially if you've done a general purpose component that you're passing around your organization. You know blood, sweat and tears into this component and some savage over in accounting decides that you know an h one should be 144 pixels well also know just blew your component out.
[00:19:02] With angular, under the hood, it leverages shadow DOM. So by default, it is emulated shadow DOM. Now CSS is no longer cascading style sheets, but it's components style sheets. And so essentially what you're doing is you're putting a perimeter around the styling of your component. And if you've ever had somebody just trample over a component and he's like this thing isn't working or you see down the one your like "What just happened".
[00:19:30] This is I would say a hedge around that. So this is super awesome. A lot of my designer friends component developers like they just, every time they do this, they just push champagne out on the ground. It's a really big feature.
>> Lucas: And so here we are simply saying, so just under here we still have our component class.
[00:19:54] But on top of it we're saying we just want to attach this template, this style sheet, and we're going to use this selector. Now we're doing this and calling an external template. There's another school of thought and I'm not going to say which one I fall into. The style guide recommends using external templates but react the pretty abolish on doing your templates in line.
[00:20:21] The reason being, and I agree with this, is that it serves as a canary in a coal mine if you will. That if your template is too big, to comfortably sit inline within your component. In other words, you're like, I'm at line 400. Like, this is really hard to understand, it's really messing everything up.
[00:20:40] Your component is probably doing too much. And so this is a way to ensure fine grain components, is by doing them inline. Now if I saw external or inline, it's not going to offend me either way. The point is your components should be single purpose, fine grained. And if your template is 1,200 lines of markup, you're probably doing too much.
[00:21:04] So favor fine grain specific units of code and functionality over these monolithic things that are doing, well, really anything more than one thing. Start thinking of a way to start abstracting that out, this is basic. Software Engineering architecture. Class just a Java script class, template is just html.
[00:21:26] So, if you know Java script you know html you're well in you're way. But, there is an assume back this up, up to this point. This really nothing to do with java are really angular. And so the question is how do we make angular aware of these things.
[00:21:46] This is where meta data comes in, so meta data allows angular to process a class and turn it or basic insert it into kind of the angular application life cycle. We attach metadata with TypeScript using decorators. So even this, I believe it's already in a proposal, is that one of the things I love about TypeScript is that they're really pushing JavaScript ahead fast.
[00:22:15] But then the things that really work and they're evolving, they basic, submitting that back to become standard. So decorators are one of these things. They're just functions, so you can actual write your own decorators. And the most common is the component decorator, which then takes essentially an object that has properties that tells Angular how the component is supposed to work.
[00:22:40] So, in this case we have a component. We're say take this class, attach this template, this CSS. And when we attach it to the DOM, do so using this selector. So think of a selector as just an HTML tag that you can then insert into the DOM.
>> Lucas: Now one thing, and we'll talk about this more tomorrow, is that even though component is the most common, is you can also decorate properties and methods.
[00:23:12] And so, input and output are kind of two big ones. So we have a component, we're saying this is an input property and it's also going to have an output event of this. And so, we'll explain this more. They're just, so you can see that sometimes it does indeed exist inside the class and this is totally normal.