6.2 Rendering Components With Router Outlets
In this lesson we'll see how to tell Angular where to render our routed components.
1.Introduction6 lessons, 42:00
2.Get Started With Angular7 lessons, 42:38
3.Core Concepts7 lessons, 55:20
4.Template Deep Dive11 lessons, 1:10:56
5.Forms10 lessons, 1:45:41
6.Routing9 lessons, 1:15:10
7.Using the HTTP Client5 lessons, 56:24
8.Testing10 lessons, 1:23:27
9.Building for Production1 lesson, 03:40
10.Conclusion1 lesson, 01:32
6.2 Rendering Components With Router Outlets
Hi folks, in this lesson we're going to see how we can wire up routes within our application and how we can control where routed components actually get rendered. I just wanna point out that because I am British, I say routes in a different way than probably most of you guys listening do. But just remember every time I say routes I mean routes. So, okay, the example application has a file that we created in the last lesson app.routes.ts, and this contains one of the route definitions for application. So you can see the file here, we won't be needing that at all now because we've already defined all of our routes. So, let's go ahead and close this now. We will need to import routes into the app module though, so let's do that. We will also need to import Angular's router module into our own module. So now we can configure the router module to use the routes that we defined the app.routes file So we passed the RouterModule to the imports array like we do with any other modules, but this module is slightly different. So we need to invoke a method now, and that method is called ForRoutes. And we can use this to pass in an array of routes. Great, so this is what we need to do to initialize our routes. So, now we need to tell Angular where we want to render our routed components. Our three routes, start, game, and end, are all situated in the home component. But now that we want to use routing, we will not be hardcoding these components directly into the home component. So, let's comment out these components and replace them with a router outlet instead. So let's test things out. So looks like there's an error in the console, we might just need to stop and start the server. Okay, it looks like everything is good, and we can see straight away in the background here that the app has been redirected to the start route. And we can see that the start component is being displayed, excellent. So let's try changing the route now. And we can see that if we change the routes to/game we now get redirected to the game component. So we do have some areas in the console here. And the reason why we're getting this is because previously we were passing the player through to the game component from the home components. And obviously we can't do that now. And so when the template tries to read the hand of the player to display the cards, it can't do that because at the moment there is no hand player. We will fix that but nevertheless, you can see how routing works a URL is entered into the browser address bar. Angular intercepts this URL and checks it against the routes defined for the application and renders the appropriate component into the router outlet. We can also see the page not found component if we try to navigate to a route that doesn't exist. So we can see that we have been successfully redirected to the page not found component. At the moment the component is empty and it just has the page not found words generic message. I'm not going to design and build some funky 404 page for this app, I'll leave that for you to have fun with on your own time. We can fix the error in the game component easily enough though. So previously it was dependent on a player being passed to the component as an input. A better way would be for us to add a player service that handles the creation of the players and which different components can use to get the players they need. So let's add this service now. Great, so Angular has created the new service and a spec file for the service. The CLI didn't update the app module with the new service because it might not be a generic service to be used throughout the application. But we will be using it in a few different places, so let's add it there ourselves, manually. So first of all, we need to import the service. And we can then add it to the providers array so that it can be injected into any other component in the application. So let's go back to the new service now. This service will contain an array of players so we should import the player model. Then we can define the array of players. The player's property can be initialized with an empty array. We can also do this in the constructor, but there's no point really. Initializing the array here saves pointless boilerplates in the constructor. The service will also have a method used to create players, so let's add this next. So the method defines a single parameter called player name,which will be a string,. And the method doesn't explicitly return anything, so we can mark it as void. Inside the method all we need to do is push a new player into the player's array. The player constructor is past the player name that the create player method will receive. Perfect, so this should be all we need to do in this service. Let's inject the service into the home component first. And we can inject it into the constructor. There isn't a constructor so let's add one. So now we can make some changes to the initialization code. So currently we create the dealer player in the ngOnImage method. We don't need to do this anymore as the player service will be responsible for creating players. So instead, let's just use the service. We can also make some other changes here. Previously, we were controlling whether the start, game, or end components were visible using the game started and game-ended properties. Now that we're rooting to these components, we no longer need these properties so we can remove them. Also the players will now be stored in the players service so we won't need this array of players anymore that can go to We won't be doing any player initialization in this component, other than using the player service. So we won't need to import the player constructor anymore, so let's get rid of that. We were using the startGame event emitted by the start component in order to create the human player. We will not be doing this either now that we have routing, in fact event handling will not even work in the same way anymore. We can leave the start game method in place for the moment but let's remove the part where we initialize the new player So the deal method of the deck of cards requires the players to be passed in. We can update this to pass in the players array from the players service instead of the local players property which no longer exists. And we won't be needing this end game method anymore either, so let's get rid of that. So in this lesson we've learned that in order to make use of routing in an Angular component we need to import Angular's routing module. We then saw that we could tell Angular about our routes using the ForRoutes method of the router module which is used to pass our array of routes into the router module. Angular will use this to initialize the routing for our application. We also saw that in order to render routed components to the screen, we need to add a router-outlet in the template. Which tells Angular where we would like to render our routed components. We also saw that the router-outlet is a simple custom element and once the route has been initialized, we need no provide any additional configuration at all. We also spent a little bit of time refactoring our home component to remove properties that are no longer necessary. And we added a play a service to handle creating and storing the players of the game. Thanks for watching.