Tuesday, April 18, 2017

Angular 2 - Routing

This is the third in a series of posts describing how to build an Angular 2 application from the ground up by using the Angular CLI.  The first installment in the series can be found here, and the second can be found here.   I'm going to build on what I did in those posts so it would probably help to at least be a little bit familiar with what I did there.  If you want to skip those first two installments you can get the code that was generated during those parts of the guide by visiting Github (here) and switching to the second-installment branch.

In this installment we're going to learn about routing.  Routing is the method we use to show different content depending on the URL the user has visited.  Routing enables us to load the majority of our resources and content once time and then inject different content whenever the user changes the route (by clicking a link, a button, changing the URL in the address bar, or some other method).  If you're still a little bit confused try to imagine a childrens toy called the View Master.  It's a set of lenses that the child can look through to see a picture.  When they click a button the picture changes.
The child doesn't have to change the entire View Master to look at a different picture, he just flicks the tab and a new picture appears for him.  Routing works the same way.  The overall structure of the page and the resources stay right where they are (this is the View Master part) and the content that is injected changes when the user clicks a button (this is the picture wheel the View Master uses).

Routing has been around for a while and Angular JS (aka Angular 1.x) had sort of a love/hate relationship with routing.  I know that I tended not to use the built-in routing in Angular 2, favoring the more robust (at the time, at least) ng-router.  In Angular 2, though, the team decided to make things easier and incorporate them a bit more.  Since the whole framework is more modular anyway it worked out quite nicely to have routing in a separate module that can be used... or not.  On a side note, the reason the team jumped over Angular 3 and went straight from 2 to 4 was they wanted to keep the version number of Angular in sync with the version number of the router.  Not pertinent in any way, but it seems like something useful to know.

Since adding routing is so easy let's just get started.  Create a new file as a sibling of app.module.ts (so mine will be created at D:\Dev\Learning\Angular2\cli\ProveIt\src\app) named routes.ts (the name doesn't matter so if you don't like routes.ts name it whatever you want).

The first thing we need to do in our new file is import Routes from @angular/router:import { Routes } from '@angular/router';

Now we need to import the components we'll use in our routes.  When someone visits http://www.mysite.com/students we want them to see our StudentsComponent, but if they visit http://www.mysite.com/student/1 we want them to see our StudentComponent for the student with id 1.  To do this we'll need to import both components in our routes.ts file.  You should know how to do that by now so I'm not going to show you.

Let's set up the routes to do what we just described.  Create and export a constant named appRoutes that is of type Routes:
export const appRoutesRoutes = [];

Now that we have our constant defined it's just a matter of adding the routes that we want.  Each route object can have a path and a component property. Create the routes (inside the appRoutes array):
path: 'students'component: StudentsComponent }, { path: 'student/:id'component: StudentComponent },

Now that we have our route constant created we need to wire it up to our module so go to your app.module.ts file and import the appRoutes constant from the routes file:import { appRoutes } from './routes'. Now we need to import RouterModule from @angular/router and use it to bring in our appRoutes constant. I'll leave the import statement to you, but here's how you'd use it (in the imports array in your @NgModule recipe):RouterModule.forRoot(appRoutes),

The last thing we need to do is change our app.component.html to use the router instead of loading our StudentsComponent directly.  We do that by modifying the html to be: <router-outlet></router-outlet>. If you're running your app you'll probably notice that now all you see is a blank screen. That's because the app is navigating to the root ("/") and we haven't configured that route. Change the URL to have /students on the end and you should see your students component.

We can actually configure the root route to redirect to our students route pretty easily so we'll go ahead and do that now.  Back in routes.ts add one more route to the list, but this one won't have a component property, it'll have a redirectTo property.  Like this:path: ''redirectTo: 'students'pathMatch: 'full' }.  With just this last change we can navigate to our root URL and be redirect to our students list (it even updates the URL in the address bar for us!).

OK, that wasn't the last thing.  We have one more optional item.  We can add a PageNotFoundComponent and redirect all other routes to go there instead of throwing an error.  The only piece of information I haven't given you to do that on your own is that the path of the route you'd want to create is **.  My final version is checked in on Github, on the routing branch.  We have a bit more to cover with routing, but this post is getting long so I'm going to end here and pick up the rest in another installment.

No comments:

Post a Comment