| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | # Routing
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | There are new requirements for the Tour of Heroes app: | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | * Add a *Dashboard* view. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | * Add the ability to navigate between the *Heroes* and *Dashboard* views. | 
					
						
							|  |  |  |  | * When users click a hero name in either view, navigate to a detail view of the selected hero. | 
					
						
							|  |  |  |  | * When users click a *deep link* in an email, open the detail view for a particular hero. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | When you’re done, users will be able to navigate the app like this: | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-09 23:53:32 +01:00
										 |  |  |  | <figure> | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  |   <img src='generated/images/guide/toh/nav-diagram.png' alt="View navigations"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | </figure> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | ## Add the _AppRoutingModule_
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | An Angular best practice is to load and configure the router in a separate, top-level module | 
					
						
							|  |  |  |  | that is dedicated to routing and imported by the root `AppModule`. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | By convention, the module class name is `AppRoutingModule` and it belongs in the `app-routing.module.ts` in the `src/app` folder. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | Use the CLI to generate it. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | <code-example language="sh" class="code-shell"> | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  |   ng generate module app-routing --flat --module=app | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | </code-example> | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  |  | <div class="l-sub-section"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | `--flat` puts the file in `src/app` instead of its own folder.<br> | 
					
						
							|  |  |  |  | `--module=app` tells the CLI to register it in the `imports` array of the `AppModule`. | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | The generated file looks like this: | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | <code-example path="toh-pt5/src/app/app-routing.module.0.ts"  | 
					
						
							|  |  |  |  |   title="src/app/app-routing.module.ts (generated)"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | </code-example> | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | You generally don't declare components in a routing module so you can delete the | 
					
						
							|  |  |  |  | `@NgModule.declarations` array and delete `CommonModule` references too. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | You'll configure the router with `Routes` in the `RouterModule` | 
					
						
							|  |  |  |  | so import those two symbols from the `@angular/router` library. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | Add an `@NgModule.exports` array with `RouterModule` in it. | 
					
						
							|  |  |  |  | Exporting `RouterModule` makes router directives available for use | 
					
						
							|  |  |  |  | in the `AppModule` components that will need them. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | `AppRoutingModule` looks like this now: | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | <code-example path="toh-pt5/src/app/app-routing.module.ts"  | 
					
						
							|  |  |  |  |   region="v1" | 
					
						
							|  |  |  |  |   title="src/app/app-routing.module.ts (v1)"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | </code-example> | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | ### Add routes
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | *Routes* tell the router which view to display when a user clicks a link or | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | pastes a URL into the browser address bar. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | A typical Angular `Route` has two properties: | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | 1. `path`: a string that matches the URL in the browser address bar. | 
					
						
							|  |  |  |  | 1. `component`: the component that the router should create when navigating to this route. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | You intend to navigate to the `HeroesComponent` when the URL is something like `localhost:4200/heroes`. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | Import the `HeroesComponent` so you can reference it in a `Route`. | 
					
						
							|  |  |  |  | Then define an array of routes with a single `route` to that component. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | <code-example path="toh-pt5/src/app/app-routing.module.ts"  | 
					
						
							|  |  |  |  |   region="heroes-route"> | 
					
						
							|  |  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | Once you've finished setting up, the router will match that URL to `path: 'heroes'`  | 
					
						
							| 
									
										
										
										
											2017-11-16 23:17:18 +09:00
										 |  |  |  | and display the `HeroesComponent`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | ### _RouterModule.forRoot()_
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | You first must initialize the router and start it listening for browser location changes. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | Add `RouterModule` to the `@NgModule.imports` array and  | 
					
						
							|  |  |  |  | configure it with the `routes` in one step by calling  | 
					
						
							|  |  |  |  | `RouterModule.forRoot()` _within_ the `imports` array, like this: | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | <code-example path="toh-pt5/src/app/app-routing.module.ts"  | 
					
						
							|  |  |  |  |   region="ngmodule-imports"> | 
					
						
							|  |  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  |  | <div class="l-sub-section"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  |   The method is called `forRoot()` because you configure the router at the application's root level. | 
					
						
							|  |  |  |  |   The `forRoot()` method supplies the service providers and directives needed for routing,  | 
					
						
							|  |  |  |  |   and performs the initial navigation based on the current browser URL. | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | ## Add _RouterOutlet_
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | Open the `AppComponent` template replace the `<app-heroes>` element with a `<router-outlet>` element. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | <code-example path="toh-pt5/src/app/app.component.html"  | 
					
						
							|  |  |  |  |   region="outlet" | 
					
						
							|  |  |  |  |   title="src/app/app.component.html (router-outlet)"> | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | </code-example> | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | You removed `<app-heroes>` because you will only display the `HeroesComponent` when the user navigates to it. | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | The `<router-outlet>` tells the router where to display routed views. | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  |  | <div class="l-sub-section"> | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | The `RouterOutlet` is one of the router directives that became available to the `AppComponent` | 
					
						
							|  |  |  |  | because `AppModule` imports `AppRoutingModule` which exported `RouterModule`. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | #### Try it
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | You should still be running with this CLI command. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | <code-example language="sh" class="code-shell"> | 
					
						
							|  |  |  |  |   ng serve | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | </code-example> | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | The browser should refresh and display the app title but not the list of heroes. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | Look at the browser's address bar.  | 
					
						
							|  |  |  |  | The URL ends in `/`. | 
					
						
							|  |  |  |  | The route path to `HeroesComponent` is `/heroes`. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | Append `/heroes` to the URL in the browser address bar. | 
					
						
							|  |  |  |  | You should see the familiar heroes master/detail view. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | {@a routerlink} | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | ## Add a navigation link (_routerLink_)
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | Users shouldn't have to paste a route URL into the address bar.  | 
					
						
							|  |  |  |  | They should be able to click a link to navigate. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | Add a `<nav>` element and, within that, an anchor element that, when clicked,  | 
					
						
							|  |  |  |  | triggers navigation to the `HeroesComponent`. | 
					
						
							|  |  |  |  | The revised `AppComponent` template looks like this: | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | <code-example  | 
					
						
							|  |  |  |  |   path="toh-pt5/src/app/app.component.html"  | 
					
						
							|  |  |  |  |   region="heroes" | 
					
						
							|  |  |  |  |   title="src/app/app.component.html (heroes RouterLink)"> | 
					
						
							|  |  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | A [`routerLink` attribute](#routerlink) is set to `"/heroes"`, | 
					
						
							|  |  |  |  | the string that the router matches to the route to `HeroesComponent`. | 
					
						
							|  |  |  |  | The `routerLink` is the selector for the [`RouterLink` directive](#routerlink) | 
					
						
							|  |  |  |  | that turns user clicks into router navigations. | 
					
						
							|  |  |  |  | It's another of the public directives in the `RouterModule`. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | The browser refreshes and displays the app title and heroes link,  | 
					
						
							|  |  |  |  | but not the heroes list. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | Click the link.  | 
					
						
							|  |  |  |  | The address bar updates to `/heroes` and the list of heroes appears. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  |  | <div class="l-sub-section"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | Make this and future navigation links look better by adding private CSS styles to `app.component.css` | 
					
						
							|  |  |  |  | as listed in the [final code review](#appcomponent) below. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | ## Add a dashboard view
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | Routing makes more sense when there are multiple views. | 
					
						
							|  |  |  |  | So far there's only the heroes view.  | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | Add a `DashboardComponent` using the CLI: | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | <code-example language="sh" class="code-shell"> | 
					
						
							|  |  |  |  |   ng generate component dashboard | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | </code-example> | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | The CLI generates the files for the `DashboardComponent` and declares it in `AppModule`. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | Replace the default file content in these three files as follows and then return for a little discussion: | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | <code-tabs> | 
					
						
							|  |  |  |  |   <code-pane  | 
					
						
							|  |  |  |  |     title="src/app/dashboard/dashboard.component.html" path="toh-pt5/src/app/dashboard/dashboard.component.1.html"> | 
					
						
							|  |  |  |  |   </code-pane> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  |   <code-pane  | 
					
						
							|  |  |  |  |     title="src/app/dashboard/dashboard.component.ts" path="toh-pt5/src/app/dashboard/dashboard.component.ts"> | 
					
						
							|  |  |  |  |   </code-pane> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  |   <code-pane  | 
					
						
							|  |  |  |  |     title="src/app/dashboard/dashboard.component.css" path="toh-pt5/src/app/dashboard/dashboard.component.css"> | 
					
						
							|  |  |  |  |   </code-pane> | 
					
						
							|  |  |  |  | </code-tabs> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | The  _template_ presents a grid of hero name links. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | * The `*ngFor` repeater creates as many links as are in the component's `heroes` array. | 
					
						
							|  |  |  |  | * The links are styled as colored blocks by the `dashboard.component.css`. | 
					
						
							|  |  |  |  | * The links don't go anywhere yet but [they will shortly](#hero-details). | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | The _class_ is similar to the `HeroesComponent` class. | 
					
						
							|  |  |  |  | * It defines a `heroes` array property. | 
					
						
							|  |  |  |  | * The constructor expects Angular to inject the `HeroService` into a private `heroService` property. | 
					
						
							|  |  |  |  | * The `ngOnInit()` lifecycle hook calls `getHeroes`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | This `getHeroes` reduces the number of heroes displayed to four | 
					
						
							|  |  |  |  | (2nd, 3rd, 4th, and 5th). | 
					
						
							| 
									
										
										
										
											2017-03-30 20:04:18 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | <code-example path="toh-pt5/src/app/dashboard/dashboard.component.ts" region="getHeroes"> | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | </code-example> | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | ### Add the dashboard route
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | To navigate to the dashboard, the router needs an appropriate route. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | Import the `DashboardComponent` in the `AppRoutingModule`. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | <code-example  | 
					
						
							|  |  |  |  |   path="toh-pt5/src/app/app-routing.module.ts"  | 
					
						
							|  |  |  |  |   region="import-dashboard"  | 
					
						
							|  |  |  |  |   title="src/app/app-routing.module.ts (import DashboardComponent)"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | </code-example> | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | Add a route to the `AppRoutingModule.routes` array that matches a path to the `DashboardComponent`. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | <code-example  | 
					
						
							|  |  |  |  |   path="toh-pt5/src/app/app-routing.module.ts"  | 
					
						
							|  |  |  |  |   region="dashboard-route"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | </code-example> | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | ### Add a default route
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | When the app starts, the browsers address bar points to the web site's root. | 
					
						
							|  |  |  |  | That doesn't match any existing route so the router doesn't navigate anywhere. | 
					
						
							|  |  |  |  | The space below the `<router-outlet>` is blank. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | To make the app navigate to the dashboard automatically, add the following | 
					
						
							|  |  |  |  | route to the `AppRoutingModule.Routes` array. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | <code-example path="toh-pt5/src/app/app-routing.module.ts" region="redirect-route"> | 
					
						
							|  |  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | This route redirects a URL that fully matches the empty path to the route whose path is `'/dashboard'`. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-12 21:17:13 +03:00
										 |  |  |  | After the browser refreshes, the router loads the `DashboardComponent` | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | and the browser address bar shows the `/dashboard` URL. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | ### Add dashboard link to the shell
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | The user should be able to navigate back and forth between the | 
					
						
							|  |  |  |  | `DashboardComponent` and the `HeroesComponent` by clicking links in the | 
					
						
							|  |  |  |  | navigation area near the top of the page. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | Add a dashboard navigation link to the `AppComponent` shell template, just above the *Heroes* link. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | <code-example path="toh-pt5/src/app/app.component.html" title="src/app/app.component.html"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | After the browser refreshes you can navigate freely between the two views by clicking the links. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | {@a hero-details} | 
					
						
							|  |  |  |  | ## Navigating to hero details
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | The `HeroDetailsComponent` displays details of a selected hero. | 
					
						
							|  |  |  |  | At the moment the `HeroDetailsComponent` is only visible at the bottom of the `HeroesComponent` | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | The user should be able to get to these details in three ways. | 
					
						
							| 
									
										
										
										
											2017-11-27 22:38:30 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | 1. By clicking a hero in the dashboard. | 
					
						
							|  |  |  |  | 1. By clicking a hero in the heroes list. | 
					
						
							|  |  |  |  | 1. By pasting a "deep link" URL into the browser address bar that identifies the hero to display. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | In this section, you'll enable navigation to the `HeroDetailsComponent` | 
					
						
							|  |  |  |  | and liberate it from the `HeroesComponent`. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | ### Delete _hero details_ from _HeroesComponent_
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | When the user clicks a hero item in the `HeroesComponent`, | 
					
						
							|  |  |  |  | the app should navigate to the `HeroDetailComponent`, | 
					
						
							|  |  |  |  | replacing the heroes list view with the hero detail view. | 
					
						
							|  |  |  |  | The heroes list view should no longer show hero details as it does now. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | Open the `HeroesComponent` template (`heroes/heroes.component.html`) and | 
					
						
							|  |  |  |  | delete the `<app-hero-detail>` element from the bottom. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | Clicking a hero item now does nothing.  | 
					
						
							|  |  |  |  | You'll [fix that shortly](#heroes-component-links) after you enable routing to the `HeroDetailComponent`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | ### Add a _hero detail_ route
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | A URL like `~/detail/11` would be a good URL for navigating to the *Hero Detail* view of the hero whose `id` is `11`.  | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | Open `AppRoutingModule` and import `HeroDetailComponent`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | <code-example  | 
					
						
							|  |  |  |  |   path="toh-pt5/src/app/app-routing.module.ts"  | 
					
						
							|  |  |  |  |   region="import-herodetail"  | 
					
						
							|  |  |  |  |   title="src/app/app-routing.module.ts (import HeroDetailComponent)"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | Then add a _parameterized_ route to the `AppRoutingModule.routes` array that matches the path pattern to the _hero detail_ view. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | <code-example  | 
					
						
							|  |  |  |  |   path="toh-pt5/src/app/app-routing.module.ts"  | 
					
						
							|  |  |  |  |   region="detail-route"> | 
					
						
							|  |  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | The colon (:) in the `path` indicates that `:id` is a placeholder for a specific hero `id`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | At this point, all application routes are in place. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | <code-example  | 
					
						
							|  |  |  |  |   path="toh-pt5/src/app/app-routing.module.ts"  | 
					
						
							|  |  |  |  |   region="routes"  | 
					
						
							|  |  |  |  |   title="src/app/app-routing.module.ts (all routes)"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | </code-example> | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | ### _DashboardComponent_ hero links
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | The `DashboardComponent` hero links do nothing at the moment. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | Now that the router has a route to `HeroDetailComponent`, | 
					
						
							|  |  |  |  | fix the dashboard hero links to navigate via the _parameterized_ dashboard route. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | <code-example  | 
					
						
							|  |  |  |  |   path="toh-pt5/src/app/dashboard/dashboard.component.html"  | 
					
						
							|  |  |  |  |   region="click"  | 
					
						
							|  |  |  |  |   title="src/app/dashboard/dashboard.component.html (hero links)"> | 
					
						
							|  |  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | You're using Angular [interpolation binding](guide/template-syntax#interpolation) within the `*ngFor` repeater  | 
					
						
							|  |  |  |  | to insert the current interation's `hero.id` into each  | 
					
						
							|  |  |  |  | [`routerLink`](#routerlink). | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | {@a heroes-component-links} | 
					
						
							|  |  |  |  | ### _HeroesComponent_ hero links
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | The hero items in the `HeroesComponent` are `<li>` elements whose click events | 
					
						
							|  |  |  |  | are bound to the component's `onSelect()` method. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | <code-example  | 
					
						
							|  |  |  |  |   path="toh-pt4/src/app/heroes/heroes.component.html"  | 
					
						
							|  |  |  |  |   region="list"  | 
					
						
							|  |  |  |  |   title="src/app/heroes/heroes.component.html (list with onSelect)"> | 
					
						
							|  |  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | Strip the `<li>` back to just its `*ngFor`, | 
					
						
							|  |  |  |  | wrap the badge and name in an anchor element (`<a>`), | 
					
						
							|  |  |  |  | and add a `routerLink` attribute to the anchor that  | 
					
						
							|  |  |  |  | is the same as in the dashboard template | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | <code-example  | 
					
						
							|  |  |  |  |   path="toh-pt5/src/app/heroes/heroes.component.html"  | 
					
						
							|  |  |  |  |   region="list"  | 
					
						
							|  |  |  |  |   title="src/app/heroes/heroes.component.html (list with links)"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | </code-example> | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | You'll have to fix the private stylesheet (`heroes.component.css`) to make | 
					
						
							|  |  |  |  | the list look as it did before. | 
					
						
							|  |  |  |  | Revised styles are in the [final code review](#heroescomponent) at the bottom of this guide. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | #### Remove dead code (optional)
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | While the `HeroesComponent` class still works,  | 
					
						
							|  |  |  |  | the `onSelect()` method and `selectedHero` property are no longer used. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | It's nice to tidy up and you'll be grateful to yourself later. | 
					
						
							|  |  |  |  | Here's the class after pruning away the dead code. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | <code-example  | 
					
						
							|  |  |  |  |   path="toh-pt5/src/app/heroes/heroes.component.ts" | 
					
						
							|  |  |  |  |   region="class"  | 
					
						
							|  |  |  |  |   title="src/app/heroes/heroes.component.ts (cleaned up)" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | </code-example> | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | ## Routable *HeroDetailComponent*
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | Previously, the parent `HeroesComponent` set the `HeroDetailComponent.hero` | 
					
						
							|  |  |  |  | property and the `HeroDetailComponent` displayed the hero. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | `HeroesComponent` doesn't do that anymore. | 
					
						
							|  |  |  |  | Now the router creates the `HeroDetailComponent` in response to a URL such as `~/detail/11`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | The `HeroDetailComponent` needs a new way to obtain the _hero-to-display_. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | * Get the route that created it,  | 
					
						
							|  |  |  |  | * Extract the `id` from the route | 
					
						
							|  |  |  |  | * Acquire the hero with that `id` from the server via the `HeroService` | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | Add the following imports: | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | <code-example  | 
					
						
							|  |  |  |  |   path="toh-pt5/src/app/hero-detail/hero-detail.component.ts"  | 
					
						
							|  |  |  |  |   region="added-imports"  | 
					
						
							|  |  |  |  |   title="src/app/hero-detail/hero-detail.component.ts"> | 
					
						
							|  |  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | {@a hero-detail-ctor} | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | Inject the `ActivatedRoute`, `HeroService`, and `Location` services | 
					
						
							|  |  |  |  | into the constructor, saving their values in private fields: | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | <code-example  | 
					
						
							|  |  |  |  |   path="toh-pt5/src/app/hero-detail/hero-detail.component.ts" region="ctor"> | 
					
						
							|  |  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | The [`ActivatedRoute`](api/router/ActivatedRoute) holds information about the route to this instance of the `HeroDetailComponent`. | 
					
						
							|  |  |  |  | This component is interested in the route's bag of parameters extracted from the URL. | 
					
						
							|  |  |  |  | The _"id"_ parameter is the `id` of the hero to display. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | The [`HeroService`](tutorial/toh-pt4) gets hero data from the remote server | 
					
						
							|  |  |  |  | and this component will use it to get the _hero-to-display_. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | The [`location`](api/common/Location) is an Angular service for interacting with the browser. | 
					
						
							|  |  |  |  | You'll use it [later](#goback) to navigate back to the view that navigated here. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | ### Extract the _id_ route parameter
 | 
					
						
							| 
									
										
										
										
											2017-03-30 20:04:18 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | In the `ngOnInit()` [lifecycle hook](guide/lifecycle-hooks#oninit) | 
					
						
							|  |  |  |  | call `getHero()` and define it as follows. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | <code-example  | 
					
						
							|  |  |  |  |   path="toh-pt5/src/app/hero-detail/hero-detail.component.ts" region="ngOnInit"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | </code-example> | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | The `route.snapshot` is a static image of the route information shortly after the component was created. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | The `paramMap` is a dictionary of route parameter values extracted from the URL. | 
					
						
							|  |  |  |  | The `"id"` key returns the `id` of the hero to fetch. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | Route parameters are always strings. | 
					
						
							|  |  |  |  | The JavaScript (+) operator converts the string to a number, | 
					
						
							|  |  |  |  | which is what a hero `id` should be. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | The browser refreshes and the app crashes with a compiler error. | 
					
						
							|  |  |  |  | `HeroService` doesn't have a `getHero()` method. | 
					
						
							|  |  |  |  | Add it now. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | ### Add *HeroService.getHero()*
 | 
					
						
							| 
									
										
										
										
											2017-03-30 20:04:18 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | Open `HeroService` and add this `getHero()` method | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | <code-example  | 
					
						
							|  |  |  |  |   path="toh-pt5/src/app/hero.service.ts"  | 
					
						
							|  |  |  |  |   region="getHero"  | 
					
						
							|  |  |  |  |   title="src/app/hero.service.ts (getHero)"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | </code-example> | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | <div class="alert is-important"> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | Note the backticks ( ` ) that  | 
					
						
							|  |  |  |  | define a JavaScript  | 
					
						
							|  |  |  |  | [_template literal_](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) for embedding the `id`. | 
					
						
							|  |  |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | Like [`getHeroes()`](tutorial/toh-pt4#observable-heroservice), | 
					
						
							|  |  |  |  | `getHero()` has an asynchronous signature. | 
					
						
							|  |  |  |  | It returns a _mock hero_ as an `Observable`, using the RxJS `of()` function. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | You'll be able to re-implement `getHero()` as a real `Http` request | 
					
						
							|  |  |  |  | without having to change the `HeroDetailComponent` that calls it. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | #### Try it
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | The browser refreshes and the app is working again. | 
					
						
							|  |  |  |  | You can click a hero in the dashboard or in the heroes list and navigate to that hero's detail view. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | If you paste `localhost:4200/detail/11` in the browser address bar, | 
					
						
							|  |  |  |  | the router navigates to the detail view for the hero with `id: 11`,  "Mr. Nice". | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | {@a goback} | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | ### Find the way back
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | By clicking the browser's back button,  | 
					
						
							|  |  |  |  | you can go back to the hero list or dashboard view, | 
					
						
							|  |  |  |  | depending upon which sent you to the detail view. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | It would be nice to have a button on the `HeroDetail` view that can do that. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | Add a *go back* button to the bottom of the component template and bind it | 
					
						
							|  |  |  |  | to the component's `goBack()` method. | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | <code-example  | 
					
						
							|  |  |  |  |   path="toh-pt5/src/app/hero-detail/hero-detail.component.html"  | 
					
						
							|  |  |  |  |   region="back-button" | 
					
						
							|  |  |  |  |   title="src/app/hero-detail/hero-detail.component.html (back button)"> | 
					
						
							|  |  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | Add a `goBack()` _method_ to the component class that navigates backward one step  | 
					
						
							|  |  |  |  | in the browser's history stack | 
					
						
							|  |  |  |  | using the `Location` service that you [injected previously](#hero-detail-ctor). | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | <code-example path="toh-pt5/src/app/hero-detail/hero-detail.component.ts" region="goBack" title="src/app/hero-detail/hero-detail.component.ts (goBack)"> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | Refresh the browser and start clicking. | 
					
						
							|  |  |  |  | Users can navigate around the app, from the dashboard to hero details and back, | 
					
						
							|  |  |  |  | from heroes list to the mini detail to the hero details and back to the heroes again. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | You've met all of the navigational requirements that propelled this page. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | ## Final code review
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | Here are the code files discussed on this page and your app should look like this <live-example></live-example>. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | {@a approutingmodule} | 
					
						
							|  |  |  |  | {@a appmodule} | 
					
						
							|  |  |  |  | #### _AppRoutingModule_ and _AppModule_
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | <code-tabs> | 
					
						
							|  |  |  |  |   <code-pane  | 
					
						
							|  |  |  |  |     title="src/app/app-routing.module.ts"  | 
					
						
							|  |  |  |  |     path="toh-pt5/src/app/app-routing.module.ts"> | 
					
						
							|  |  |  |  |   </code-pane> | 
					
						
							|  |  |  |  |   <code-pane  | 
					
						
							|  |  |  |  |     title="src/app/app.module.ts"  | 
					
						
							|  |  |  |  |     path="toh-pt5/src/app/app.module.ts"> | 
					
						
							|  |  |  |  |   </code-pane> | 
					
						
							|  |  |  |  | </code-tabs> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | {@a appcomponent} | 
					
						
							|  |  |  |  | #### _AppComponent_
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | <code-tabs> | 
					
						
							|  |  |  |  |   <code-pane  | 
					
						
							|  |  |  |  |     title="src/app/app.component.html" | 
					
						
							|  |  |  |  |     path="toh-pt5/src/app/app.component.html"> | 
					
						
							|  |  |  |  |   </code-pane> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  |   <code-pane  | 
					
						
							|  |  |  |  |     title="src/app/app.component.css" | 
					
						
							|  |  |  |  |     path="toh-pt5/src/app/app.component.css"> | 
					
						
							|  |  |  |  |   </code-pane> | 
					
						
							|  |  |  |  | </code-tabs> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | {@a dashboardcomponent} | 
					
						
							|  |  |  |  | #### _DashboardComponent_
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | <code-tabs> | 
					
						
							|  |  |  |  |   <code-pane  | 
					
						
							|  |  |  |  |     title="src/app/dashboard/dashboard.component.html" path="toh-pt5/src/app/dashboard/dashboard.component.html"> | 
					
						
							|  |  |  |  |   </code-pane> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  |   <code-pane  | 
					
						
							|  |  |  |  |     title="src/app/dashboard/dashboard.component.ts" path="toh-pt5/src/app/dashboard/dashboard.component.ts"> | 
					
						
							|  |  |  |  |   </code-pane> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  |   <code-pane  | 
					
						
							|  |  |  |  |     title="src/app/dashboard/dashboard.component.css" path="toh-pt5/src/app/dashboard/dashboard.component.css"> | 
					
						
							|  |  |  |  |   </code-pane> | 
					
						
							|  |  |  |  | </code-tabs> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | {@a heroescomponent} | 
					
						
							|  |  |  |  | #### _HeroesComponent_
 | 
					
						
							|  |  |  |  | <code-tabs> | 
					
						
							|  |  |  |  |   <code-pane  | 
					
						
							|  |  |  |  |     title="src/app/heroes/heroes.component.html" path="toh-pt5/src/app/heroes/heroes.component.html"> | 
					
						
							|  |  |  |  |   </code-pane> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  |   <code-pane  | 
					
						
							|  |  |  |  |     title="src/app/heroes/heroes.component.ts"  | 
					
						
							|  |  |  |  |     path="toh-pt5/src/app/heroes/heroes.component.ts"> | 
					
						
							|  |  |  |  |   </code-pane> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  |   <code-pane  | 
					
						
							|  |  |  |  |     title="src/app/heroes/heroes.component.css"  | 
					
						
							|  |  |  |  |     path="toh-pt5/src/app/heroes/heroes.component.css"> | 
					
						
							|  |  |  |  |   </code-pane> | 
					
						
							|  |  |  |  | </code-tabs> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | {@a herodetailcomponent} | 
					
						
							|  |  |  |  | #### _HeroDetailComponent_
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | <code-tabs> | 
					
						
							|  |  |  |  |   <code-pane  | 
					
						
							|  |  |  |  |     title="src/app/hero-detail/hero-detail.component.html" path="toh-pt5/src/app/hero-detail/hero-detail.component.html"> | 
					
						
							|  |  |  |  |   </code-pane> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  |   <code-pane  | 
					
						
							|  |  |  |  |     title="src/app/hero-detail/hero-detail.component.ts" path="toh-pt5/src/app/hero-detail/hero-detail.component.ts"> | 
					
						
							|  |  |  |  |   </code-pane> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  |   <code-pane  | 
					
						
							|  |  |  |  |     title="src/app/hero-detail/hero-detail.component.css" path="toh-pt5/src/app/hero-detail/hero-detail.component.css"> | 
					
						
							|  |  |  |  |   </code-pane> | 
					
						
							|  |  |  |  | </code-tabs> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | ## Summary
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | * You added the Angular router to navigate among different components. | 
					
						
							| 
									
										
										
										
											2017-11-13 21:38:03 -05:00
										 |  |  |  | * You turned the `AppComponent` into a navigation shell with `<a>` links and a `<router-outlet>`. | 
					
						
							| 
									
										
										
										
											2017-11-06 19:02:18 +01:00
										 |  |  |  | * You configured the router in an `AppRoutingModule`  | 
					
						
							|  |  |  |  | * You defined simple routes, a redirect route, and a parameterized route. | 
					
						
							|  |  |  |  | * You used the `routerLink` directive in anchor elements. | 
					
						
							|  |  |  |  | * You refactored a tightly-coupled master/detail view into a routed detail view. | 
					
						
							|  |  |  |  | * You used router link parameters to navigate to the detail view of a user-selected hero. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | * You shared the `HeroService` among multiple components. |