- Read Tutorial
- Watch Guide Video
Now that we have our components organized Let's start building in some routing. Routing in Angular two is much more straightforward than in Angular one. I think that you if you're coming from that framework then you're going to be pleasantly surprised on how straightforward it is. The reason why I like it is because it's very component based. So it is completely separated from some of the kind of older ways of doing it. If you're coming from some older frameworks that have some very convoluted concepts on how routing works the way angular does it is pretty straightforward and it's just based on structuring it on which components you have and how you want them to be directed.
I'm going to come up because we don't want to have our routes cluttering up our components because that is one way you could do it you could structure your route so there and here, inside the app.components.ts
file, but that would be bad practice. Instead you want to come in and right click on app and we're going to create a new file and we're going to call it app-routing.model.ts
.
Because this is a module. This is not a component.
Everything's still working on this side. We need to do a few imports here. So we need to import NgModule, and from here we need to import this from angular/core.
import { NgModule } from '@angular/core';
We also need to import a couple of other items. We need to import the router module, and then the routes module.
import { RouterModule, Routes } from '@angular/router';
And these ones can both be found inside of inside of the '@angular/router';
. As you can see, our intellisense is now back and working.
Right now our site only has one component, so in order to make this work we need to import that component as well. I'm going to put import and we'll say home page component. Then you pass in the path, so you have to just say where you're importing it from. So you know that we've saved that in the directory home page followed by home page dot component. And that is it.
import { HomepageComponent } from './homepage/homepage.component';
Now we have access to this component that we have imported.
The next thing to do is we're going to create a variable and it's going to be a variable that's going to be a constant because we do not want this changing. You wouldn't want one part of the application dynamically changing the route names or something like that. That would break some things. So I'm going to say const routes:
, and then pass in, because this is typescript, we pass in types. This is going to be routes. This is the data type which is routes and we're getting that because we were able to import this from the router library. So all of the different things that we have all the functions we're going to call inside of this are all available to us because of the way that routes are structured. I'm going to set this equal to an array, and inside of this array is where we will place all of our routes. Nice and straightforward like that. These are set up similar to a JSON object. The first one in here is going to be path
, and this is going to be the root path. The root path is not going to actually have a path because this is the root path, and then we're going to call the function redirectTo
, and then we're going to make up one of our names for the function. This is going to be redirect to home which we've not created yet so this would not work right now.
Then there's one other thing, and a lot of the tutorials that I've read up on for some reason didn't include this but, you need to also, on your root, say pathMatch
and then pass in full
. This isn't something that you would put on your other routes. This is only on your root route here. Then you give a comma and we're going to follow this up by our next route. Our next one is simply going to be to home. This is going to not redirect to anything and it's not going to have the path match but, what it is going to have is it's going to have our component. And if you may have guessed we're bringing in the home page component.
const routes: Routes = [ { path: '', redirectTo: '/home', pathMatch: 'full' }, { path: 'home', component: HomepageComponent }, ]
And that is all we have to do inside of our routes in order to get that at least to find. Now what we have to do is because this is a module we need to actually define what's inside of it. So we'll start off with our decorator. NgModule is a class decorator so we need to pass in some metadata. First thing we're going to pass in is router module. And if you notice we have this right up here. And in order for this to work we also need to call a function on this so we're going to put forRoot
, and then pass in our variable of routes. So we're going to put NgModule, imports RouterModule dot forRoot and then pass in routes here. Then because of how this is structured we also need to give some exports. Here we're going to export the router module. We don't want the forRoot just the router module by itself. And because this is simply a class decorator, now we actually have to give the class. We're going to put export class AppRoutingModule and it's going to be an empty one so just have the curly brackets right after it. Now if I hit save everything is good to go.
@NgModule({ imports: [ RoutingModule.forRoot(routes) ], exports: [ RouterModule ] }) export class AppRoutingModule {}
Nothing is changing on the screen over here and that's for a couple of reasons. That's because we're not done yet. First we have to go to index.html
and right above the title tag we need to establish a base. So I'm going to put base
and then pass in an href
and this is something that Angular is going to look at and it's going to be looking for what that base is. And in this case we were saying that we want the base to simply be an empty route. So we're not passing any parameters or anything like that.
In early versions of angular if you have ever noticed a web URL that had a route and then right after the URL there was a slash and then the pound sign, that was the early way that Angular dealt with routing. In Angular two it's become much more advanced and you can do things like this where you don't have that ugly pound sign right in the middle of your path.
So that is the first part. And now we have to import this because our actual app module doesn't know anything about our routes yet. We need to open up app.module.ts
and we're going to do a couple things. First we're going to import our router. We're going to import AppRouting
and this is not a component, this is a module. We want to import this right here and we can get rid of this code
and I'm going to put dot slash app routing module. As you can see that fixes our error messages. The next thing that we need to do is just to import it. So I'm going to give a comma and then just copy and paste our app routing module and save.
And it looks like we have a little bit of an error. So let's see what this is. Notice how our console gives us this right here.
So it says, See image above
So it just keeps on repeating the same thing right here. And this is happening because? Let's go open up our app component. I forget to put one thing that should fix it. In our template, and eventually we're gonna move our template into its own file but, I'm going to save that for another episode. So before we do that we're going to do some string interpolation. Get rid of these quotation marks and replace them with back ticks. And if you remember the back tick is that character right above your tab key. We're going to do this and this is going to allow us to put our view code on multiple lines just like this. We need to provide what's called a router outlet. I'm going to type <router-outlet>
. Close it off and then give a closing tag right here. If I hit save, now that fixed the error message here.
and now you can see that our home value is there. So what this is doing is it's bringing in the home page component. If you're wondering what this is, router outlet is saying, look in the router and anything that gets pulled in from the router is going to slide in to wherever this router is placed. A good example of this is, since you're coming from the Rails perspective, if you remember how Rails deals with their master layout and how they have the yield in the middle of that layout. This router outlet functions like that. Let me show you how that will work. If I have navigation and I come down here and I say footer. Now if I hit save here. You can see that now footer has slid in underneath that.
So router outlet is saying that whatever components you pass in from the router are going to be passed in right here with this router outlet.
Get rid of this because we're not going to be using that. And just to test out to make sure that all this is wired up let's open up our home page component. And we're going to change this to say home page.
Hit save, and on the right hand side you'll see that now it says home page. So that is all working properly. One other thing that you'll know and, I'm going to pull this open so you can see the full URL, is if I hit delete here and just go to localhost:3000
you can see that it is automatically redirecting to home.
One thing that may be a little bit different about this and it's not going to make a ton of sense until we start adding other components is that angular does not work like a regular crud based application, or a regular, I should say, server side kind of application. Angular works all on a single page application kind of structure which means that even though we have routes here, and these are routes that you can pass off and can send to people and they can access the site. Even though we have that the way the Angular does it, it never leaves the page. So in other words there are no page refreshes as far as Angular is concerned. It is always going to be a single page and it's dynamically via Ajax and via the way that the whole Angular structure is built in. It just pulls whatever is called onto the page. In our case we're using that router outlet and it's being called right here and as we add more components it's going to make a lot more sense. But that's what I really wanted to stress is, imagine you have a Rails app and it's a regular monolithic app that has views and everything like that. If you have a page that says Home
and then you have another page that says About Us
, if you send to users from home to about us there's going to be a page refresh. And those are two distinct pages on the application with Angular it does not work like that. With Angular all it sees is one single application. When you click links and you perform tasks all it's doing is it's sliding those values in so that they can be shown to the users. And when you use routes then they'll be called up here. But these are more of a reference for parameters and for the kind of the way the system works and last for you know creating hardcoded routes so the way that you do on server side kind of applications. Like I said it's going to make a lot more sense once we start adding other components because you'll be able to click around and access other parts of it and we'll get into that over the next couple episodes.
So that's the way that you can implement routing into an Angular two app and in the next guide we're going to start structuring our files so that we're no longer embedding our templates inside of the component decorator. And we're going to start building some view files.