2016-02-05 23:27:06 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								include ../_util-fns
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  The Angular ***Router*** enables navigation from one [view](./glossary.html#view) to the next
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  as users perform application tasks.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We cover the router's primary features in this chapter, illustrating them through the evolution
							 
						 
					
						
							
								
									
										
										
										
											2016-07-30 21:00:52 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  of a small application that we can <live-example>run live</live-example>.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  img(src='/resources/images/devguide/plunker-separate-window-button.png' alt="pop out the window" align="right" style="margin-right:-20px")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    To see the URL changes in the browser address bar,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    pop out the preview window by clicking the blue 'X' button in the upper right corner.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.l-main-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ## Overview
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The browser is a familiar model of application navigation.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We enter a URL in the address bar and the browser navigates to a corresponding page.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We click links on the page and the browser navigates to a new page.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We click the browser's back and forward buttons and the browser navigates
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  backward and forward through the history of pages we've seen.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  The Angular ***Router*** ("the router") borrows from this model.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  It can interpret a browser URL as an instruction
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  to navigate to a client-generated view and pass optional parameters along to the supporting view component
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  to help it decide what specific content to present.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We can bind the router to links on a page and it will navigate to
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  the appropriate application view when the user clicks a link.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We can navigate imperatively when the user clicks a button, selects from a drop box,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  or in response to some other stimulus from any source. And the router logs activity
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  in the browser's history journal so the back and forward buttons work as well.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We'll learn many router details in this chapter which covers
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * Setting the [base href](#base-href)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * Importing from the [router library](#import)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * [configuring the router](#route-config)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * the [link parameters array](#link-parameters-array) that propels router navigation
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * navigating when the user clicks a data-bound [RouterLink](#router-link)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * navigating under [program control](#navigate)
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  * retrieving information from the [route](#activated-route)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * [animating](#route-animation) transitions for route components
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * navigating [relative](#relative-navigation) to our current URL
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  * toggling css classes for the [active router link](#router-link-active)
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  * embedding critical information in the URL with [route parameters](#route-parameters)
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  * providing non-critical information in [optional route parameters](#optional-route-parameters)
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  * add [child routes](#child-routing-component) under a feature section
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  * [grouping child routes](#component-less-route) without a component
							 
						 
					
						
							
								
									
										
										
										
											2016-06-17 22:55:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  * [redirecting](#redirect) from one route to another
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  * confirming or canceling navigation with [guards](#guards)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    * [CanActivate](#can-activate-guard) to prevent navigation to a route
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    * [CanActivateChild](#can-activate-child-guard) to prevent navigation to a child route
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    * [CanDeactivate](#can-deactivate-guard) to prevent navigation away from the current route
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    * [Resolve](#resolve-guard) to pre-fetch data before activating a route
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    * [CanLoad](#can-load-guard) to prevent asynchronous routing
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  * providing optional information across routes with [query parameters](#query-parameters)
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  * jumping to anchor elements using a [fragment](#fragment)
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  * loading feature areas [asynchronously](#asynchronous-routing)
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  * choosing the "HTML5" or "hash" [URL style](#browser-url-styles)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We proceed in phases marked by milestones building from a simple two-pager with placeholder views
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  up to a modular, multi-view design with child routes.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  But first, an overview of router basics.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.l-main-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ## The Basics
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Let's begin with a few core concepts of the Router.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Then we can explore the details through a sequence of examples.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ### *<base href>*
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Most routing applications should add a `<base>` element to the **`index.html`** as the first child in the  `<head>` tag
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  to tell the router how to compose navigation URLs.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  If the `app` folder is the application root, as it is for our sample application,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  set the `href` value *exactly* as shown here.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('index.1.html', 'base-href')
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ### Router imports
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  The Angular Router is an optional service that presents a particular component view for a given URL.
							 
						 
					
						
							
								
									
										
										
										
											2016-09-20 05:24:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  It is not part of the Angular core. It is in its own library package, `@angular/router`.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We import what we need from it as we would from any other Angular package.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								+makeExcerpt('app/app.routing.ts (import)', 'import-router')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    We cover other options in the [details below](#browser-url-styles).
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ### Configuration
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The application will have one *`router`*. When the browser's URL changes, the router looks for a corresponding **`Route`**
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  from which it can determine the component to display.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  A router has no routes until we configure it.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We bootstrap our application with an array of routes that we'll provide to our **`RouterModule.forRoot`** function.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  In the following example, we configure our application with four route definitions.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/app.routing.1.ts (excerpt)', 'route-config')
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    The `Routes` is an array of *routes* that describe how to navigate.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Each *Route* maps a URL `path` to a component.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-17 22:55:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    There are no **leading slashes** in our **path**. The router parses and builds the URL for us,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    allowing us to use relative and absolute paths when navigating between application views.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    The `:id` in the first route is a token for a route parameter. In a URL such as `/hero/42`, "42"
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    is the value of the `id` parameter. The corresponding `HeroDetailComponent`
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    will use that value to find and present the hero whose `id` is 42.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    We'll learn more about route parameters later in this chapter.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    The `data` property in the third route is a place to store arbitrary data associated with each
							 
						 
					
						
							
								
									
										
										
										
											2016-08-14 13:54:33 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    specific route. This data is accessible within each activated route and can be used to store
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    items such as page titles, breadcrumb text and other read-only data. We'll use the [resolve guard](#resolve-guard)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    to retrieve additional data later in the chapter.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    The `empty path` in the fourth route matches as the default path for each level of routing. It
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    also allows for adding routes without extending the URL path.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    The `**` in the last route denotes a **wildcard** path for our route. The router will match this route
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if the URL requested doesn't match any paths for routes defined in our configuration. This is useful for
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    displaying a 404 page or redirecting to another route.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    **The order of the routes in the configuration matters** and this is by design. The router uses a **first-match wins**
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    strategy when matching routes, so more specific routes should be placed above less specific routes. In our
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    configuration above, the routes with a static path are listed first, followed by an empty path route,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    that matches as the default route. The wildcard route is listed last as it's the most generic route and should be
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    matched **only** if no other routes are matched first.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    We export the `routing` constant so we can import it into our `app.module.ts` file where we'll add
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    a configured *Router* module to our `AppModule` imports.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Next we open `app.module.ts` where we must register our routing, routing providers, and declare our two route components.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/app.module.1.ts (basic setup)', 'router-basics')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ### Router Outlet
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Given this configuration, when the browser URL for this application becomes `/heroes`,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  the router matches that URL to the `Route` path `/heroes` and displays the `HeroListComponent`
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  in a **`RouterOutlet`** that we've placed in the host view's HTML.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								code-example(language="html").
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  <!-- Routed views go here -->
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  <router-outlet></router-outlet>
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ### Router Links
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Now we have routes configured and a place to render them, but
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  how do we navigate? The URL could arrive directly from the browser address bar.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  But most of the time we navigate as a result of some user action such as the click of
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  an anchor tag.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We add a **`RouterLink`** directive to the anchor tag. Since
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  we know our link doesn't contain any dynamic information, we can use a one-time binding to our route *path*.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  If our `RouterLink` needed to be more dynamic we could bind to a template expression that
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  returns an array of route link parameters (the **link parameters array**). The router ultimately resolves that array
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  into a URL and a component view.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We also add a **`RouterLinkActive`** directive to each anchor tag to add or remove CSS classes to the
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  element when the associated *RouterLink* becomes active. The directive can be added directly on the element
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  or on its parent element.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We see such bindings in the following `AppComponent` template:
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/app.component.1.ts', 'template', '')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 :marked
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								   We're adding two anchor tags with `RouterLink` and `RouterLinkActive` directives.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   We bind each `RouterLink` to a string containing the path of a route.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								   '/crisis-center' and '/heroes' are the paths of the `Routes` we configured above.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								   We'll learn to write link expressions — and why they are arrays —
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								   [later](#link-parameters-array) in the chapter.
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   We define `active` as the CSS class we want toggled to each `RouterLink` when they become
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   the current route using the `RouterLinkActive ` directive. We could add multiple classes to
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   the `RouterLink` if we so desired.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ### Router State
							 
						 
					
						
							
								
									
										
										
										
											2016-08-02 07:39:11 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  After the end of each successful navigation lifecycle, the router builds a tree of `ActivatedRoute` objects
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  that make up the current state of the router. We can access the current `RouterState` from anywhere in our
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  application using the `Router` service and the `routerState` property.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The router state provides us with methods to traverse up and down the route tree from any activated route
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  to get information we may need from parent, child and sibling routes.
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ### Let's summarize
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The application is provided with a configured router.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The component has a `RouterOutlet` where it can display views produced by the router.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  It has `RouterLink`s that users can click to navigate via the router.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Here are the key *Router* terms and their meanings:
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								table
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  tr
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    th Router Part
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    th Meaning
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  tr
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    td <code>Router</code>
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    td.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      Displays the application component for the active URL.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      Manages navigation from one component to the next.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  tr
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    td <code>RouterModule</code>
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    td.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      A separate Angular module that provides the necessary service providers
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      and directives for navigating through application views.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  tr
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    td <code>Routes</code>
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    td.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      Defines an array of Routes, each mapping a URL path to a component.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  tr
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    td <code>Route</code>
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    td.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-17 22:55:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      Defines how the router should navigate to a component based on a URL pattern.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      Most routes consist of a path and a component type.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  tr
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    td <code>RouterOutlet</code>
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    td.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      The directive (<code><router-outlet></code>) that marks where the router should display a view.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  tr
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    td <code>RouterLink</code>
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    td.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      The directive for binding a clickable HTML element to
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      a route. Clicking an anchor tag with a <code>routerLink</code> directive
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      that is bound to a <i>string</i> or a <i>Link Parameters Array</i> triggers a navigation.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  tr
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    td <code>RouterLinkActive</code>
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    td.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      The directive for adding/removing classes from an HTML element when an associated
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      routerLink contained on or inside the element becomes active/inactive.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  tr
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    td <code>ActivatedRoute</code>
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    td.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      A service that is provided to each route component that contains route specific
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      information such as route parameters, static data, resolve data, global query params and the global fragment.
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  tr
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    td <code>RouterState</code>
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    td.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      The current state of the router including a tree of the currently activated
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      routes in our application along convenience methods for traversing the route tree.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  tr
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    td <code><i>Link Parameters Array</i></code>
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    td.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      An array that the router interprets into a routing instruction.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      We can bind a <code>RouterLink</code> to that array or pass the array as an argument to
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      the <code>Router.navigate</code> method.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  tr
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    td <code><i>Routing Component</i></code>
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    td.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-29 17:51:04 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      An Angular component with a <code>RouterOutlet</code> that displays views based on router navigations.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We've barely touched the surface of the router and its capabilities.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The following detail sections describe a sample routing application
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  as it evolves over a sequence of milestones.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We strongly recommend taking the time to read and understand this story.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.l-main-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ## The Sample Application
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We have an application in mind as we move from milestone to milestone.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    While we make incremental progress toward the ultimate sample application, this chapter is not a tutorial.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    We discuss code and design decisions pertinent to routing and application design.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    We gloss over everything in between.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-30 21:00:52 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    The full source is available in the <live-example></live-example>.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Our client is the Hero Employment Agency.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Heroes need work and The Agency finds Crises for them to solve.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  The application has three main feature areas:
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  1. A *Crisis Center* where we maintain the list of crises for assignment to heroes.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  1. A *Heroes* area where we maintain the list of heroes employed by The Agency.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  1. An *Admin* area where we manage the list of crises and heroes displayed.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-30 21:00:52 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Run the <live-example></live-example>.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  It opens in the *Crisis Center*.  We'll come back to that.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Click the *Heroes* link. We're presented with a list of Heroes.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								figure.image-display
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  img(src='/resources/images/devguide/router/hero-list.png' alt="Hero List" width="250")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We select one and the application takes us to a hero editing screen.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								figure.image-display
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  img(src='/resources/images/devguide/router/hero-detail.png' alt="Crisis Center Detail" width="250")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Our changes take effect immediately. We click the "Back" button and the
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  app returns us to the Heroes list.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We could have clicked the browser's back button instead.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  That would have returned us to the Heroes List as well.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Angular app navigation updates the browser history as normal web navigation does.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Now click the *Crisis Center* link. We go to the *Crisis Center* and its list of ongoing crises.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								figure.image-display
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  img(src='/resources/images/devguide/router/crisis-center-list.png' alt="Crisis Center List" )
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We select one and the application takes us to a crisis editing screen.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								figure.image-display
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  img(src='/resources/images/devguide/router/crisis-center-detail.png' alt="Crisis Center Detail")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  This is a bit different from the *Hero Detail*. *Hero Detail* saves the changes as we type.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  In *Crisis Detail* our changes are temporary until we either save or discard them by pressing the "Save" or "Cancel" buttons.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Both buttons navigate back to the *Crisis Center* and its list of crises.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Suppose we click a crisis, make a change, but ***do not click either button***.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Maybe we click the browser back button instead. Maybe we click the "Heroes" link.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Do either. Up pops a dialog box.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								figure.image-display
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  img(src='/resources/images/devguide/router/confirm-dialog.png' alt="Confirm Dialog" width="300")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We can say "OK" and lose our changes or click "Cancel" and continue editing.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The router supports a `CanDeactivate` guard that gives us a chance to clean-up
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  or ask the user's permission before navigating away from the current view.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Here we see an entire user session that touches all of these features.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								<a id="full-app-demo"></a>
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								figure.image-display
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  img(src='/resources/images/devguide/router/router-anim.gif' alt="App in action" )
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Here's a diagram of all application routing options:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								figure.image-display
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  img(src='/resources/images/devguide/router/complete-nav.png' alt="Navigation diagram" )
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  This app illustrates the router features we'll cover in this chapter
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  * organizing the application features into modules
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  * navigating to a component (*Heroes* link to "Heroes List")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * including a route parameter (passing the Hero `id` while routing to the "Hero Detail")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * child routes (the *Crisis Center* has its own routes)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * the `CanActivate` guard (checking route access)
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  * the `CanActivateChild` guard (checking child route access)
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  * the `CanDeactivate` guard (ask permission to discard unsaved changes)
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  * the `Resolve` guard (pre-fetching route data)
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  * lazy loading feature modules
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * the `CanLoad` guard (check before loading feature module assets)
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								<a id="getting-started"></a>
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.l-main-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ## Milestone #1: Getting Started with the Router
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Let's begin with a simple version of the app that navigates between two empty views.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								figure.image-display
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  img(src='/resources/images/devguide/router/router-1-anim.gif' alt="App in action" )
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								a#base-href
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ### Set the *<base href>*
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  The Router uses the browser's
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  [history.pushState](https://developer.mozilla.org/en-US/docs/Web/API/History_API#Adding_and_modifying_history_entries)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  for navigation. Thanks to `pushState`, we can make our in-app URL paths look the way we want them to
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  look, e.g. `localhost:3000/crisis-center`. Our in-app URLs can be indistinguishable from server URLs.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Modern HTML 5 browsers were the first to support `pushState` which is why many people refer to these URLs as
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  "HTML 5 style" URLs.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We must **add a [<base href> element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base) tag**
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  to the `index.html` to make `pushState` routing work.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The browser also needs the base `href` value to prefix *relative* URLs when downloading and linking to
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  css files, scripts, and images.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Add the base element just after the  `<head>` tag.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  If the `app` folder is the application root, as it is for our application,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  set the `href` value in **`index.html`** *exactly* as shown here.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								+makeExcerpt('index.1.html', 'base-href')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    HTML 5 style navigation is the Router default.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Learn why "HTML 5" style is preferred, how to adjust its behavior, and how to switch to the
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    older hash (#) style if necessary in the [Browser URL Styles](#browser-url-styles) appendix below.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    #### Live example note
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    We have to get tricky when we run the live example because the host service sets
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    the application base address dynamically. That's why we replace the `<base href...>` with a
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    script that writes a `<base>` tag on the fly to match.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  code-example(format="")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    <script>document.write('<base href="' + document.location + '" />');</script>
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    We should only need this trick for the live example, not production code.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ### Configure the routes for the Router
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We begin by importing some symbols from the router library.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  The Router is in its own `@angular/router` package.
							 
						 
					
						
							
								
									
										
										
										
											2016-09-20 05:24:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  It's not part of the Angular core. The router is an optional service because not all applications
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  need routing and, depending on your requirements, you may need a different routing library.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We teach our router how to navigate by configuring it with routes.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We recommend creating a separate `app.routing.ts` file dedicated to this purpose.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Here is our first configuration. We pass the array of routes to the `RouterModule.forRoot` method
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  which returns a module containing the configured `Router` service provider ... and some other,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  unseen providers that the routing library requires. We export this as the `routing` token.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								+makeExcerpt('app/app.routing.2.ts')
							 
						 
					
						
							
								
									
										
										
										
											2016-06-17 22:55:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    We also export an empty `appRoutingProviders` array
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    so we can simplify registration of router dependencies later in `app.module.ts`.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    We don't have any providers to register right now. But we will.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								a#route-config
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								h4#define-routes Define routes
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  A router must be configured with a list of route definitions.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Our first configuration defines an array of two routes with simple paths leading to the
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  `CrisisListComponent` and `HeroListComponent` components.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 00:04:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Each definition translates to a [Route](../api/router/index/Route-interface.html) object which has a
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  `path`, the URL path segment for this route, and a
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  `component`, the component associated with this route.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The router draws upon its registry of such route definitions when the browser URL changes
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  or when our code tells the router to navigate along a route path.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  In plain English, we might say of the first route:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * *When the browser's location URL changes to match the path segment `/crisis-center`, create or retrieve an instance of
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  the `CrisisListComponent` and display its view.*
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * *When the application requests navigation to the path `/crisis-center`, create or retrieve an instance of
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  the `CrisisListComponent`, display its view, and update the browser's address location and history with the URL
							 
						 
					
						
							
								
									
										
										
										
											2016-06-17 22:55:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  for that path.*
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Learn about *providers* in the [Dependency Injection](dependency-injection.html#!#injector-providers) chapter.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								h4#register-providers Register routing in the AppModule
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Our app launches from the `app.module.ts` file in the `/app` folder.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We import the `routing` token we exported from the `app.routing.ts` file and add it to the `imports` array.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We import our `CrisisListComponent` and `HeroListComponent` components and add them to our *declarations*
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  so they will be registered within our `AppModule`.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We also import the `appRoutingProviders` array and add it to the `providers` array.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/app.module.1.ts')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Providing the router module in our `AppModule` makes the Router available everywhere in our application.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								h3#shell The <i>AppComponent</i> shell
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The root `AppComponent` is the application shell. It has a title at the top, a navigation bar with two links,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  and a *Router Outlet* at the bottom where the router swaps views on and off the page. Here's what we mean:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								figure.image-display
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  img(src='/resources/images/devguide/router/shell-and-outlet.png' alt="Shell" width="300" )
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								a#shell-template
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The corresponding component template looks like this:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								+makeExcerpt('app/app.component.1.ts', 'template', '')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								a#router-outlet
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  ### *RouterOutlet*
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  `RouterOutlet` is a component from the router library.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The router displays views within the bounds of the `<router-outlet>` tags.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    A template may hold exactly one ***unnamed*** `<router-outlet>`.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-17 22:55:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    The router supports multiple *named* outlets, a feature we'll cover in future.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								a#router-link
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  ### *RouterLink* binding
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Above the outlet, within the anchor tags, we see [Property Bindings](template-syntax.html#property-binding) to
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  the `RouterLink` directive that look like `routerLink="..."`. We use the `RouterLink` from the router library.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  The links in this example each have a string path, the path of a route that
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  we configured earlier. We don't have route parameters yet.
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We can also add more contextual information to our `RouterLink` by providing query string parameters
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  or a URL fragment for jumping to different areas on our page. Query string parameters
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  are provided through the `[queryParams]` binding which takes an object (e.g. `{ name: 'value' }`), while the URL fragment
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  takes a single value bound to the `[fragment]` input binding.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Learn about the how we can also use the **link parameters array** in the [appendix below](#link-parameters-array).
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								a#router-link-active
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								h3#router-link <i>RouterLinkActive</i> binding
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  On each anchor tag, we also see [Property Bindings](template-syntax.html#property-binding) to
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  the `RouterLinkActive` directive that look like `routerLinkActive="..."`.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The template expression to the right of the equals (=) contains our space-delimited string of CSS classes.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We can also bind to the `RouterLinkActive` directive using an array of classes
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  such as `[routerLinkActive]="['...']"`.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The `RouterLinkActive` directive toggles css classes for active `RouterLink`s based on the current `RouterState`.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  This cascades down through each level in our route tree, so parent and child router links can be active at the same time.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  To override this behavior, we can bind to the `[routerLinkActiveOptions]` input binding with the `{ exact: true }` expression.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  By using `{ exact: true }`, a given `RouterLink` will only be active if its URL is an exact match to the current URL.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								h3#router-directives <i>Router Directives</i>
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  `RouterLink`, `RouterLinkActive` and `RouterOutlet` are directives provided by the Angular `RouterModule` package.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  They are readily available for us to use in our template.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The current state of `app.component.ts` looks like this:
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/app.component.1.ts')
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ### "Getting Started" wrap-up
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We've got a very basic, navigating app, one that can switch between two views
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  when the user clicks a link.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We've learned how to
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * load the router library
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  * add a nav bar to the shell template with anchor tags, `routerLink`  and `routerLinkActive` directives
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  * add a `router-outlet` to the shell template where views will be displayed
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * configure the router module with `RouterModule.forRoot`
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  * set the router to compose "HTML 5" browser URLs.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The rest of the starter app is mundane, with little interest from a router perspective.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Here are the details for readers inclined to build the sample through to this milestone.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Our starter app's structure looks like this:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.filetree
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  .file router-sample
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  .children
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    .file app
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      .children
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        .file app.component.ts
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        .file app.module.ts
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        .file app.routing.ts
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        .file crisis-list.component.ts
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        .file hero-list.component.ts
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        .file main.ts
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    .file node_modules ...
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    .file typings ...
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    .file index.html
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    .file package.json
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    .file styles.css
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    .file tsconfig.json
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    .file typings.json
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Here are the files discussed in this milestone
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								+makeTabs(
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  `router/ts/app/app.component.1.ts,
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  router/ts/app/app.module.1.ts,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  router/ts/app/app.routing.2.ts,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  router/ts/app/main.ts,
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  router/ts/app/hero-list.component.ts,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  router/ts/app/crisis-list.component.ts,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  router/ts/index.html`,
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  ',,,,',
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  `app.component.ts,
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  app.module.ts,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  app.routing.ts,
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  main.ts,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  hero-list.component.ts,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  crisis-list.component.ts,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  index.html`)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								.l-main-section#heroes-feature
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  ## Milestone #2: The Heroes Feature
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We've seen how to navigate using the `RouterLink` directive.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Now we'll learn some new tricks such as how to
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  * organize our app and routes into *feature areas* using modules
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  * navigate imperatively from one component to another
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  * pass required and optional information in route parameters
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  To demonstrate, we'll build out the *Heroes* feature.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ### The Heroes "feature area"
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  A typical application has multiple *feature areas*, each an island of functionality
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  with its own workflow(s), dedicated to a particular business purpose.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We could continue to add files to the `app/` folder.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  That's unrealistic and ultimately not maintainable.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We think it's better to put each feature area in its own folder.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Our first step is to **create a separate `app/heroes/` folder**
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  and add *Hero Management* feature files there.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We won't be creative about it. Our example is pretty much a
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  copy of the code and capabilities in the "[Tutorial: Tour of Heroes](../tutorial/index.html)".
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Here's how the user will experience this version of the app
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								figure.image-display
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  img(src='/resources/images/devguide/router/router-2-anim.gif' alt="App in action" )
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ### Add Heroes functionality
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We want to break our app out into different *feature modules* that we then import
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  into our main module so it can make use of them. First, we'll create a `heroes.module.ts`
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  in our heroes folder.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We delete the placeholder `hero-list.component.ts` that's in
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  the `app/` folder.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We create a new `hero-list.component.ts` in the `app/heroes/`
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  folder and copy over the contents of the final `heroes.component.ts` from the tutorial.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We copy the `hero-detail.component.ts` and the `hero.service.ts` files
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  into the `heroes/` folder.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We provide the `HeroService` in the `providers` array of our `Heroes` module
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  so its available to all components within our module.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Our `Heroes` module is ready for routing.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/heroes/heroes.module.1.ts')
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  When we're done organizing, we have four *Hero Management* files:
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.filetree
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  .file app/heroes
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  .children
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    .file hero-detail.component.ts
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    .file hero-list.component.ts
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    .file hero.service.ts
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    .file heroes.module.ts
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Now it's time for some surgery to bring these files and the rest of the app
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  into alignment with our application router.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ### *Hero* feature routing requirements
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The new Heroes feature has two interacting components, the list and the detail.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The list view is self-sufficient; we navigate to it, it gets a list of heroes and displays them.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  It doesn't need any outside information.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The detail view is different. It displays a particular hero. It can't know which hero on its own.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  That information must come from outside.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  In our example, when the user selects a hero from the list, we navigate to the detail view to show that hero.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We'll tell the detail view which hero to display by including the selected hero's id in the route URL.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ### *Hero* feature route configuration
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-17 22:55:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We recommend giving each feature area its own route configuration file.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Create a new `heroes.routing.ts` in the `heroes` folder like this:
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/heroes/heroes.routing.ts')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We use the same techniques we learned for `app.routing.ts`.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We import the two components from their new locations in the `app/heroes/` folder, define the two hero routes.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  and add export our `heroesRouting` that returns configured `RouterModule` for our feature module.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Now that we have routes for our `Heroes` module, we'll need to register them with the *Router*.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We'll import the *RouterModule* like we did in the `app.routing.ts`, but there is a slight difference here.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  In our `app.routing.ts`, we used the static **forRoot** method to register our routes and application level
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  service providers. In a feature module we use static **forChild** method.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    The **RouterModule.forRoot** should only be provided for the `AppModule`. Since we are in a feature
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    module, we'll use **RouterModule.forChild** method to only register additional routes.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We import our `heroesRouting` token from `heroes.routing.ts` into our `Heroes` module and register the routing.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/heroes/heroes.module.ts (heroes routing)', 'heroes-routes')
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  ### Route definition with a parameter
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The route to `HeroDetailComponent` has a twist.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								+makeExcerpt('app/heroes/heroes.routing.ts (excerpt)', 'hero-detail-route')
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Notice the `:id` token in the path. That creates a slot in the path for a **Route Parameter**.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  In this case, we're expecting the router to insert the `id` of a hero into that slot.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  If we tell the router to navigate to the detail component and display "Magneta", we expect hero `id` (15) to appear in the
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  browser URL like this:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								code-example(format="." language="bash").
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  localhost:3000/hero/15
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  If a user enters that URL into the browser address bar, the router should recognize the
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  pattern and go to the same "Magneta" detail view.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    #### Route parameter: Required or optional?
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Embedding the route parameter token, `:id`, in the route definition path is a good choice for our scenario
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    because the `id` is *required* by the `HeroDetailComponent` and because
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    the value `15` in the path clearly distinguishes the route to "Magneta" from
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    a route for some other hero.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    An [optional-route-parameter](#optional-route-parameter) might be a better choice if we were passing an *optional* value to `HeroDetailComponent`.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								a#navigate
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  ### Navigate to hero detail imperatively
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-17 22:55:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  *We won't navigate to the detail component by clicking a link*
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  so we won't be adding a new `RouterLink` anchor tag to the shell.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Instead, when the user *clicks* a hero in the list, we'll *command* the router
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  to navigate to the hero detail view for the selected hero.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We'll adjust the `HeroListComponent` to implement these tasks, beginning with its constructor
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  which acquires the router service and the `HeroService` by dependency injection:
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/heroes/hero-list.component.1.ts (constructor)', 'ctor')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We make a few changes to the template:
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/heroes/hero-list.component.1.ts', 'template', '')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The template defines an `*ngFor` repeater such as [we've seen before](displaying-data.html#ngFor).
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  There's a `(click)` [EventBinding](template-syntax.html#event-binding) to the component's `onSelect` method
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  which we implement as follows:
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								+makeExcerpt('app/heroes/hero-list.component.1.ts', 'select')
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  It calls the router's **`navigate`** method with a **Link Parameters Array**. We can use this same syntax
							 
						 
					
						
							
								
									
										
										
										
											2016-07-19 21:59:34 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  with a `RouterLink` if we want to use it in HTML rather than code.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								h3#route-parameters Setting the route parameters in the list view
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We're navigating to the `HeroDetailComponent` where we expect to see the details of the selected hero.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We'll need *two* pieces of information: the destination and the hero's `id`.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Accordingly, the *link parameters array* has *two* items:  the **path** of the destination route and a **route parameter** that specifies the
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  `id` of the selected hero.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								+makeExcerpt('app/heroes/hero-list.component.1.ts', 'link-parameters-array')
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The router composes the appropriate two-part destination URL from this array:
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								code-example(language="bash").
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  localhost:3000/hero/15
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								a#get-route-parameter
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  ### Getting the route parameter in the details view
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  How does the target `HeroDetailComponent` learn about that `id`?
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Certainly not by analyzing the URL!  That's the router's job.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The router extracts the route parameter (`id:15`) from the URL and supplies it to
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  the `HeroDetailComponent` via the **ActivatedRoute** service.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								<a id="activated-route"></a>
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								h3#activated-route ActivatedRoute: the one-stop-shop for route information
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Each route contains information about its path, data parameters, URL segment and much more.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  All of this information is available in an injected service provided by the router called the [ActivatedRoute](../api/router/index/ActivatedRoute-interface.html).
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The `ActivatedRoute` contains all the information you need from the current route component as well as ways to get information
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  about other activated routes in the `RouterState`.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    **`url`**: An `Observable` of the route path(s). The value is provided as an array of strings for each part of the route path.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    **`data`**: An `Observable` that contains the `data` object provided for the route. Also contains any resolved values from the [resolve guard](#resolve-guard).
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    **`params`**: An `Observable` that contains the required and [optional parameters](#optional-route-parameters) specific to the route.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    **`queryParams`**: An `Observable` that contains the [query parameters](#query-parameters) available to all routes.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    **`fragment`**:  An `Observable` of the URL [fragment](#fragment) available to all routes.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    **`outlet`**: The name of the `RouterOutlet` used to render the route. For an unnamed outlet, the outlet name is **primary**.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    **`routeConfig`**: The route configuration used for the route that contains the origin path.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    **`parent`**: an `ActivatedRoute` that contains the information from the parent route when using [child routes](#child-routing-component).
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    **`firstChild`**: contains the first `ActivatedRoute` in the list of child routes.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    **`children`**: contains all the [child routes](#child-routing-component) activated under the current route.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We import the `Router`, `ActivatedRoute`, and `Params` tokens from the router package.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/heroes/hero-detail.component.1.ts (activated route)', 'imports')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								a#hero-detail-ctor
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  As usual, we write a constructor that asks Angular to inject services
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  that the component requires and reference them as private variables.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/heroes/hero-detail.component.ts (constructor)', 'ctor')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Later, in the `ngOnInit` method,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  we use the `ActivatedRoute` service to retrieve the parameters for our route.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Since our parameters are provided as an `Observable`, we use the _forEach_ method to retrieve them for the `id` parameter by name and
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  tell the `HeroService` to fetch the hero with that `id`.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								+makeExcerpt('app/heroes/hero-detail.component.ts (ngOnInit)', 'ngOnInit')
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Angular calls the `ngOnInit` method shortly after creating an instance of the `HeroDetailComponent`.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    We put the data access logic in the `ngOnInit` method rather than inside the constructor
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    to improve the component's testability.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    We explore this point in greater detail in the [OnInit appendix](#onInit) below.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Learn about the `ngOnInit` method in the
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    [Lifecycle Hooks](lifecycle-hooks.html) chapter.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								h4#reuse Observable <i>params</i> and component re-use
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  In this example, we retrieve the route params from an `Observable`.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  That implies that the route params can change during the lifetime of this component.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-17 22:55:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  They might. By default, the router reuses a component instance when it re-navigates to the same component type
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  without visiting a different component first. The parameters can change between each re-use.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-17 22:55:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Suppose a parent component navigation bar had "forward" and "back" buttons
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  that scrolled through the list of heroes.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Each click navigated imperatively to the `HeroDetailComponent` with the next or previous `id`.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We don't want the router to remove the current `HeroDetailComponent` instance from the
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  DOM only to re-create it for the next `id`.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  That could be visibly jarring.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Better to simply re-use the same component instance and update the parameter.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-17 22:55:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  But `ngOnInit` is only called once per instantiation.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We need a way to detect when the route parameters change from _within the same instance_.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The observable `params` property handles that beautifully.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								h4#snapshot <i>Snapshot</i>: the no-observable alternative
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-06-17 22:55:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  This application won't reuse the `HeroDetailComponent`.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We always return to the hero list to select another hero to view.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  There's no way to navigate from hero detail to hero detail
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  without visiting the list component in between.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  That means we get a new `HeroDetailComponent` instance every time.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Suppose we know for certain that `HeroDetailComponent` will *never, never, ever*
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  be re-used. We'll always re-create the component each time we navigate to it.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The router offers a *Snapshot* alternative that gives us the initial value of the route parameters.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We don't need to subscribe or unsubscribe.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  It's much simpler to write and read:
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								+makeExcerpt('app/heroes/hero-detail.component.2.ts (ngOnInit snapshot)', 'snapshot')
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    **Remember:** we only get the _initial_ value of the parameters with this technique.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-17 22:55:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Stick with the observable `params` approach if there's even a chance that we might navigate
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    to this component multiple times in a row.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    We are leaving the observable `params` strategy in place just in case.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								a#nav-to-list
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  ### Navigating back to the list component
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  The `HeroDetailComponent` has a "Back" button wired to its `gotoHeroes` method that navigates imperatively
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  back to the `HeroListComponent`.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The router `navigate` method takes the same one-item *link parameters array*
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  that we can bind to a `[routerLink]` directive.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  It holds the **path to the `HeroListComponent`**:
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								+makeExcerpt('app/heroes/hero-detail.component.1.ts (excerpt)', 'gotoHeroes')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.l-main-section#optional-route-parameters
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ### Route Parameters
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We use [*route parameters*](#route-parameters) to specify a *required* parameter value *within* the route URL
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  as we do when navigating to the `HeroDetailComponent` in order to view-and-edit the hero with *id:15*.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								code-example(format="." language="bash").
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  localhost:3000/hero/15
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Sometimes we wish to add *optional* information to a route request.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  For example, the `HeroListComponent` doesn't need help to display a list of heroes.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  But it might be nice if the previously-viewed hero were pre-selected when returning from the `HeroDetailComponent`.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								figure.image-display
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  img(src='/resources/images/devguide/router/selected-hero.png' alt="Selected hero")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  That becomes possible if we can include hero Magneta's `id` in the URL when we
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return from the `HeroDetailComponent`, a scenario we'll pursue in a moment.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Optional information takes other forms. Search criteria are often loosely structured, e.g., `name='wind*'`.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Multiple values are common — `after='12/31/2015' & before='1/1/2017'` — in no particular order —
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   `before='1/1/2017' & after='12/31/2015'` — in a variety of formats — `during='currentYear'` .
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  These kinds of parameters don't fit easily in a URL *path*. Even if we could define a suitable URL token scheme,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  doing so greatly complicates the pattern matching required to translate an incoming URL to a named route.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Optional parameters are the ideal vehicle for conveying arbitrarily complex information during navigation.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Optional parameters aren't involved in pattern matching and affords enormous flexibility of expression.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The Router supports navigation with optional parameters as well as required route parameters.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We define _optional_ parameters in an *object* after we define our required route parameters.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ### Route Parameters: Required or Optional?
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  There is no hard-and-fast rule. In general,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  *prefer a required route parameter when*
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * the value is required.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * the value is necessary to distinguish one route path from another.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  *prefer an optional parameter when*
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * the value is optional, complex, and/or multi-variate.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  <a id="route-parameters-object"></a>
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ### Route parameter
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  When navigating to the `HeroDetailComponent` we specified the _required_ `id` of the hero-to-edit in the
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  *route parameter* and made it the second item of the [*link parameters array*](#link-parameters-array).
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/heroes/hero-list.component.1.ts', 'link-parameters-array')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The router embedded the `id` value in the navigation URL because we had defined it
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  as a route parameter with an `:id` placeholder token in the route `path`:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/heroes/heroes.routing.ts', 'hero-detail-route')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  When the user clicks the back button, the `HeroDetailComponent` constructs another *link parameters array*
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  which it uses to navigate back to the `HeroListComponent`.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/heroes/hero-detail.component.1.ts', 'gotoHeroes')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  This array lacks a route parameter because we had no reason to send information to the `HeroListComponent`.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Now we have a reason. We'd like to send the id of the current hero with the navigation request so that the
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  `HeroListComponent` can highlight that hero in its list. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  This is a _nice-to-have_ feature; the list will display perfectly well without it.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We do that with an object that contains an _optional_ `id` parameter.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  For demonstration purposes, we also defined a junk parameter (`foo`) that the `HeroListComponent` should ignore.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Here's the revised navigation statement:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/heroes/hero-detail.component.ts (go to heroes)', 'gotoHeroes-navigate')
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  The application still works. Clicking "back" returns to the hero list view.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Look at the browser address bar.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  img(src='/resources/images/devguide/plunker-separate-window-button.png' alt="pop out the window" align="right" style="margin-right:-20px")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    When running in plunker, pop out the preview window by clicking the blue 'X' button in the upper right corner.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 It should look something like this, depending on where you run it:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								code-example(language="bash").
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  localhost:3000/heroes;id=15;foo=foo
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The `id` value appears in the URL as (`;id=15;foo=foo`), not in the URL path.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The path for the "Heroes" route doesn't have an `:id` token.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The optional route parameters are not separated by "?" and "&" as they would be in the URL query string.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  They are **separated by semicolons ";"**
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  This is *matrix URL* notation — something we may not have seen before.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    *Matrix URL* notation is an idea first floated
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    in a [1996 proposal](http://www.w3.org/DesignIssues/MatrixURIs.html) by the founder of the web, Tim Berners-Lee.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Although matrix notation never made it into the HTML standard, it is legal and
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    it became popular among browser routing systems as a way to isolate parameters
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    belonging to parent and child routes. The Router is such a system and provides
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    support for the matrix notation across browsers.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    The syntax may seem strange to us but users are unlikely to notice or care
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    as long as the URL can be emailed and pasted into a browser address bar
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    as this one can.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ### Route parameters in the *ActivatedRoute* service
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The list of heroes is unchanged. No hero row is highlighted.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    The <live-example></live-example> *does* highlight the selected
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    row because it demonstrates the final state of the application which includes the steps we're *about* to cover.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    At the moment we're describing the state of affairs *prior* to those steps.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The `HeroListComponent` isn't expecting any parameters at all and wouldn't know what to do with them.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Let's change that.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Previously, when navigating from the `HeroListComponent` to the `HeroDetailComponent`,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  we subscribed to the route params `Observable` and made it available to the `HeroDetailComponent`
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  in the `ActivatedRoute` service. We injected that service in the constructor of the `HeroDetailComponent`.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  This time we'll be navigating in the opposite direction, from the `HeroDetailComponent` to the `HeroListComponent`.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  First we extend the router import statement to include the `ActivatedRoute` service symbol;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/heroes/hero-list.component.ts (import)', 'import-router')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Then we use the `ActivatedRoute` to access the `params` _Observable_ so we can subscribe
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  and extract the `id` parameter as the `selectedId`:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/heroes/hero-list.component.ts (constructor)', 'ctor')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    All route/query parameters are strings.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    The (+) in front of the `params['id']` expression is a JavaScript trick to convert the string to an integer.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We add an `isSelected` method that returns true when a hero's id matches the selected id.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/heroes/hero-list.component.ts', 'isSelected')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Finally, we update our template with a [Class Binding](template-syntax.html#class-binding) to that `isSelected` method.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The binding adds the `selected` CSS class when the method returns `true` and removes it when `false`.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Look for it within the repeated `<li>` tag as shown here:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/heroes/hero-list.component.ts', 'template')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  When the user navigates from the heroes list to the "Magneta" hero and back, "Magneta" appears selected:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								figure.image-display
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  img(src='/resources/images/devguide/router/selected-hero.png' alt="Selected List" )
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The optional `foo` route parameter is harmless and continues to be ignored.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								h3#route-animation Adding animations to the route component
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Our heroes feature module is almost complete, but what is a feature without some smooth transitions?
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We already know that Angular supports [animations](../guide/animations.html) and we want to take
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  advantage of them by adding some animation to our *Hero Detail* component.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  First, we'll start by importing our animation functions that build our animation triggers,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  control state and manage transitions between states. We'll use these functions to add transitions
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  to our route component as it moves between states our application view. We'll also import the
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  `HostBinding` decorator for binding to our route component.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/heroes/hero-detail.component.ts (animation imports)', 'route-animation-imports')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Next, we'll use a **host binding** for route animations named *@routeAnimation*. There is nothing special
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  about the choice of the binding name, but since we are controlling route animation, we'll go with `routeAnimation`.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The binding value is set to `true` because we only care about the `*` and `void` states which are
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  [entering and leaving](../guide/animations.html#example-entering-and-leaving) animation states.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We'll also add some display and positioning bindings for styling.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/heroes/hero-detail.component.ts (route animation binding)', 'route-animation-host-binding')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Now we can build our animation trigger, which we'll call *routeAnimation* to match the binding we previously
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  setup. We'll use the **wildcard state** that matches any animation state our route component is in, along with
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  two *transitions*. One transition animates the component as it enters the application view (`void => *`), while the other
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  animates the component as it leaves the application view (`* => void`).
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We could add different transitions to different route components depending on our needs. We'll just animate our `HeroDetailComponent` for this milestone.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Using route animations on individual components is something we don't want to do throughout our entire application.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    It would be better to animate routes based on **route paths**, a topic to cover in a future update to this chapter.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Our route component animation looks as such:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/heroes/hero-detail.component.ts (route animation)', 'route-animation')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Simply stated, our `HeroDetailComponent` will ease in from the left when routed to and will slide down when navigating away.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We could add more complex animations here, but we'll leave our `HeroDetailComponent` as is for now.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								h3#merge-hero-routes Import hero module into AppModule
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Our heroes feature module is ready, but application doesn't know about our heroes module yet.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We'll need to import it into the `AppModule` we defined in `app.module.ts`.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Update `app.module.ts` as follows:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								+makeExcerpt('app/app.module.2.ts (heroes module import)', 'hero-import')
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We imported the `HeroesModule` and added it to our `AppModule`'s `imports`.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We removed the `HeroListComponent` from the `AppModule`'s `declarations` because its being provided by the `HeroesModule`
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  now. This is important because their can be only **one** owner for a declared component. In our case, the `Heroes` module is
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  the owner of the `Heroes` components and is making them available to the `AppModule`.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Routes provided by feature modules will be combined together into their imported module's routes by
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    the router. This allows us to continue defining our feature module routes without
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    modifying our main route configuration.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  As a result, the `AppModule` no longer has specific knowledge of the hero feature, its components, or its route details.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We can evolve the hero feature with more components and different routes.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  That's a key benefit of creating a separate module for each feature area.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Since our `Heroes` routes are defined within our feature module, we can also remove our initial `heroes` route from the `app.routing.ts`.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								+makeExcerpt('app/app.routing.3.ts (v2)', '')
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ### Heroes App Wrap-up
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We've reached the second milestone in our router education.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We've learned how to
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * organize our app into *feature areas*
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * navigate imperatively from one component to another
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * pass information along in route parameters and subscribe to them in our component
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  * import our feature area NgModule into our `AppModule`
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * apply animations to our route component
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  After these changes, the folder structure looks like this:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.filetree
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  .file router-sample
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  .children
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    .file app
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    .children
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      .file heroes
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      .children
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        .file hero-detail.component.ts
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        .file hero-list.component.ts
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        .file hero.service.ts
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        .file heroes.module.ts
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        .file heroes.routing.ts
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      .file app.component.ts
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      .file app.module.ts
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      .file app.routing.ts
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      .file crisis-list.component.ts
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      .file main.ts
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    .file node_modules ...
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    .file typings ...
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    .file index.html
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    .file package.json
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    .file styles.css
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    .file tsconfig.json
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    .file typings.json
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  <a id="heroes-app-code"></a>
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ### The Heroes App code
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Here are the relevant files for this version of the sample application.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								+makeTabs(
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  `router/ts/app/app.component.1.ts,
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								   router/ts/app/app.module.2.ts,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   router/ts/app/app.routing.3.ts,
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								   router/ts/app/heroes/hero-list.component.ts,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   router/ts/app/heroes/hero-detail.component.ts,
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								   router/ts/app/heroes/hero.service.ts,
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								   router/ts/app/heroes/heroes.module.ts,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   router/ts/app/heroes/heroes.routing.ts`,
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								   null,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  `app.component.ts,
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  app.module.ts,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  app.routing.ts,
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  hero-list.component.ts,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  hero-detail.component.ts,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  hero.service.ts,
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  heroes.module.ts,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  heroes.routing.ts`)
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								.l-main-section#crisis-center-feature
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ## Milestone #3: The Crisis Center
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  The *Crisis Center* is a fake view at the moment. Time to make it useful.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  The new *Crisis Center* begins as a virtual copy of the *Heroes* module.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We create a new `app/crisis-center` folder, copy the Hero files,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  and change every mention of "hero" to "crisis".
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  A `Crisis` has an `id` and `name`, just like a `Hero`
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The new `CrisisListComponent` displays lists of crises.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  When the user selects a crisis, the app navigates to the `CrisisDetailComponent`
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  for display and editing of the crisis name.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Voilà, another feature module!
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  There's no point to this exercise unless we can learn something.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We do have new ideas and techniques in mind:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-30 16:45:47 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  * We'd like our route URLs to branch in to child route trees that reflect the component trees in our feature areas.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * The application should navigate to the *Crisis Center* by default.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * The router should prevent navigation away from the detail view while there are pending changes.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * The user should be able to cancel unwanted changes.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * The router should block access to certain features until the user logs-in.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  * Our `CrisisService` is only needed within the *Crisis Center* module.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We should limit access to it to that module.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  * Changes to a feature module such as *Crisis Center* shouldn't provoke changes to the `AppModule` or
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  any other feature's component.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We need to [*separate our concerns*](https://blog.8thlight.com/uncle-bob/2014/05/08/SingleReponsibilityPrinciple.html).
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We'll address all of these issues in the *Crisis Center*
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  starting with the introduction of **child routes**
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    We'll leave *Heroes* in its less-than-perfect state to
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    serve as a contrast with what we believe to be a superior *Crisis Center* design.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ### A Crisis Center with child routes
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We'll organize the *Crisis Center* to conform to the following recommended pattern for Angular applications.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  * each feature area in its own folder within a defined module
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  * each area with its own area root component
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * each area root component with its own router-outlet and child routes
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * area routes rarely (if ever) cross
							 
						 
					
						
							
								
									
										
										
										
											2016-06-17 22:55:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  If we had many feature areas, their component trees might look like this:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								figure.image-display
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  img(src='/resources/images/devguide/router/component-tree.png' alt="Component Tree" )
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								a#child-routing-component
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  ### Child Routing Component
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Add the following `crisis-center.component.ts` to the `crisis-center` folder:
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								+makeExcerpt('app/crisis-center/crisis-center.component.ts (minus imports)', 'minus-imports')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The `CrisisCenterComponent` is much like the `AppComponent` shell.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * It is the root of the *Crisis Center* area
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  just as `AppComponent` is the root of the entire application.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * It is a shell for the crisis management feature area
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  just as the `AppComponent` is a shell to manage the high-level workflow.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * It is dead simple — simpler even than the `AppComponent` template.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  It has no content, no links, just a `<router-outlet>` for the *Crisis Center* child views.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-17 22:55:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Unlike `AppComponent` (and most other components), it **lacks a selector**.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  It doesn't need one. We don't *embed* this component in a parent template.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We *navigate* to it from the outside, via the router.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
									
										
										
										
											2016-05-02 16:53:25 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    We *can* give it a selector. There's no harm in it.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Our point is that we don't *need* one because we only *navigate* to it.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ### Service isolation
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  The `CrisisService` is neither needed nor wanted outside the *Crisis Center* domain.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Instead of registering it with the `AppModule`'s providers —
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  which makes it visible everywhere —
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  we register the `CrisisService` in the `CrisisCenterModule` providers array.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/crisis-center/crisis-center.module.1.ts', 'providers', '')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  This limits the scope of the `CrisisService` to the *Crisis Center* routes.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  No module outside of the *Crisis Center* can access it.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  There's a practical benefit to restricting its scope in this way.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  First we can evolve the service independently of the rest of the application
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  without fear of breaking what should be unrelated modules.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-17 22:55:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Second, we can delay loading this service into memory until we need it.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-17 22:55:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We can remove it from the application launch bundle,
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  reducing the size of the initial payload and improving performance.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We can load it optionally, [asynchronously](#asynchronous-routing) with the other *Crisis Center* components
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  if and when the user begins that workflow.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ### Child Route Configuration
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  The `CrisisCenterComponent` is a *Routing Component* like the `AppComponent`.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  It has its own `RouterOutlet` and its own child routes.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Add the following `crisis-center-home.component.ts` to the `crisis-center` folder.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/crisis-center/crisis-center-home.component.ts (minus imports)', 'minus-imports')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We create a `crisis-center.routing.ts` file as we did the `heroes.routing.ts` file.
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  But this time we define **child routes** *within* the parent `crisis-center` route.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/crisis-center/crisis-center.routing.1.ts (Routes)', 'routes')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Notice that the parent `crisis-center` route has a `children` property
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  with a single route containing our `CrisisListComponent`. The `CrisisListComponent` route
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  also has a `children` array with two routes.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-17 22:55:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  These two routes navigate to the two *Crisis Center* child components,
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  `CrisisCenterHomeComponent` and `CrisisDetailComponent`.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  There are some *important differences* in the treatment of these routes.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  The router displays the components of these routes in the `RouterOutlet`
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  of the `CrisisCenterComponent`, not in the `RouterOutlet` of the `AppComponent` shell.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  The `CrisisListComponent` contains the crisis list and a `RouterOutlet` to
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  display the `Crisis Center Home` and `Crisis Detail` route components.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The `Crisis Detail` route is a child of the `Crisis List`. Since the router [reuses components](#reuse)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  by default, the `Crisis Detail` component will be re-used as we select different crises.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  In contrast, back in the `Hero Detail` route, the component was recreated each time we selected a different hero.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  At the top level, paths that begin with `/` refer to the root of the application.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  But these are child routes.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  They *extend* the path of the parent route.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  With each step down the route tree, we add a slash followed by the route path (unless the route path is _empty_).
							 
						 
					
						
							
								
									
										
										
										
											2016-06-17 22:55:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-18 04:56:55 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  For example, the parent path to the `CrisisCenterComponent` is `/crisis-center`
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The router appends these child paths to the parent path to the `CrisisCenterComponent` (`/crisis-center`).
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-18 04:56:55 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  * to navigate to the `CrisisCenterHomeComponent`, the full URL is `/crisis-center` (`/crisis-center` + `''` + `''`).
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  * to navigate to the `CrisisDetailComponent` for a crisis with `id=2`, the full URL is
							 
						 
					
						
							
								
									
										
										
										
											2016-09-18 04:56:55 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  `/crisis-center/2` (`/crisis-center` + `''` + `'/2'`).
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The absolute URL for the latter example, including the origin, is
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								code-example.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  localhost:3000/crisis-center/2
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Here's the complete `crisis-center.routing.ts` file with its imports.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/crisis-center/crisis-center.routing.1.ts', '')
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								h3#import-crisis-module Import crisis center module into the AppModule routes
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  As with the `Heroes` module, we must import the `Crisis Center` module into the `AppModule`:
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								+makeExcerpt('app/app.module.3.ts (Crisis Center Module)', 'crisis-center-module')
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We also remove the initial crisis center route from our `app.routing.ts`. Our routes
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  are now being provided by our `HeroesModule` and our `CrisisCenter` feature modules. We'll keep our `app.routing.ts` file
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  for general routes which we'll cover later in the chapter.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								+makeExcerpt('app/app.routing.4.ts (v3)', '')
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-17 22:55:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								a#redirect
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  ### Redirecting routes
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  When the application launches, the initial URL in the browser bar is something like:
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								code-example.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  localhost:3000
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  That doesn't match any of our configured routes which means that our application won't display any component when it's launched.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The user must click one of the navigation links to trigger a navigation and display something.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-01 00:11:33 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We prefer that the application display the list of crises as it would if the user clicked the "Crisis Center" link or pasted `localhost:3000/crisis-center/` into the address bar.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-17 22:55:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  This is our intended default route.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-05 21:20:33 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  The preferred solution is to add a `redirect` route that transparently translates from the initial relative URL (`''`)
							 
						 
					
						
							
								
									
										
										
										
											2016-07-02 15:51:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  to the desired default path (`/crisis-center`):
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/crisis-center/crisis-center.routing.2.ts' , 'redirect', '')
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-17 22:55:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-07-01 00:11:33 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  A redirect route requires a `pathMatch` property to tell the router how to match a URL to the path of a route.
							 
						 
					
						
							
								
									
										
										
										
											2016-07-02 15:51:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  In this app, the router should select the route to the `CrisisListComponent` when the *entire URL* matches `''`,
							 
						 
					
						
							
								
									
										
										
										
											2016-07-01 00:11:33 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  so we set the `pathMatch` value to `'full'`.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-17 22:55:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
									
										
										
										
											2016-07-05 21:20:33 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Technically, `pathMatch = 'full'` results in a route hit when the *remaining*, unmatched segments of the URL match `''`.
							 
						 
					
						
							
								
									
										
										
										
											2016-07-02 15:51:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    In our example, the redirect is at the top level of the route configuration tree so the *remaining* URL and the *entire* URL
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    are the same thing.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-05 21:20:33 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    The other possible `pathMatch` value is `'prefix'` which tells the router
							 
						 
					
						
							
								
									
										
										
										
											2016-07-02 15:51:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    to match the redirect route when the *remaining* URL ***begins*** with the redirect route's _prefix_ path.
							 
						 
					
						
							
								
									
										
										
										
											2016-07-05 21:20:33 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    That's not what we want to do here. If the `pathMatch` value were `'prefix'`,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    _every_ URL would match `''`.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    We could never navigate to `/crisis-center/1` because the redirect route would match first and
							 
						 
					
						
							
								
									
										
										
										
											2016-07-02 15:51:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    send us to the `CrisisListComponent`.
							 
						 
					
						
							
								
									
										
										
										
											2016-07-05 21:20:33 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-02 15:51:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    We should redirect to the `CrisisListComponent` _only_ when the _entire (remaining)_ url is  `''`.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-05 21:20:33 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Learn more in Victor Savkin's blog
							 
						 
					
						
							
								
									
										
										
										
											2016-07-02 15:51:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    [post on redirects](http://victorsavkin.com/post/146722301646/angular-router-empty-paths-componentless-routes).
							 
						 
					
						
							
								
									
										
										
										
											2016-07-01 00:11:33 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    We'll discuss redirects in more detail in a future update to this chapter.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-17 22:55:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  The updated route definitions look like this:
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/crisis-center/crisis-center.routing.2.ts (routes v2)' , 'routes')
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								.l-main-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								h2#relative-navigation Relative Navigation
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  While building out our *Crisis Center* feature, we've navigated to the
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  *Crisis Detail* route using an **absolute path** that begins with a **slash**.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  This navigation starts from the top of our route configuration to find the
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  matching path to our route.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We could continue to use absolute paths to navigate inside our *Crisis Center*
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  feature, but that makes our links very rigid. If we changed our parent `/crisis-center`
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  path, we would have to change our link parameters array.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We can make our links more flexible by using **relative** navigation with the router.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * The full path to the route is not required.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * Navigation within our feature area remains intact if the parent route path is changed.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * The *link parameters array* only contains navigation relative to the current URL.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    The **link parameters array** supports a directory-like syntax for relative navigation.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    `./` or `no leading slash` is relative to the current level.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    `../` to go up one level in the route path.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    The relative navigation syntax can be used in combination with a *path*. If we wanted to navigate
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    from one route path to another sibling route path we could use `../path` convention to go up
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    one level and down to the sibling route path.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  In order to navigate relatively using the `Router` service, we use the `ActivatedRoute`
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  to give the router knowledge of where we are in the *RouterState*, which is our tree of
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  activated routes. We do this by adding an object as the second argument in our
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  `router.navigate` method after the *link parameters array* specifying the **relativeTo** property.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We set the `relativeTo` property to our `ActivatedRoute` and the router will merge our
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  navigation information into to the current URL.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    When using router's `navigateByUrl` method, the navigation is **always** absolute.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ### Navigate to Crisis Detail relatively
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Let's update our *Crisis List* `onSelect` method to use relative navigation so we don't have
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  to start from the top of our route configuration. We've already injected the `ActivatedRoute`
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  into our constructor that we'll need for the relative navigation.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/crisis-center/crisis-list.component.1.ts (constructor)', 'relative-navigation-ctor')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  When we visit the *Crisis Center*, our path is `/crisis-center`, so we just want to add the `id` of the *Crisis Center*
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  to our existing path. When the router navigates, it will use the current path `/crisis-center`,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  adding on our `id`. If our `id` were `1`, the resulting path would be `/crisis-center/1`.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/crisis-center/crisis-list.component.ts (relative navigation)', 'relative-navigation')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We'll also update the *Crisis Detail* component to navigate back to our *Crisis Center* list. We want to go back up a level
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  in the path, so we use to the `../` syntax. If our current `id` is `1`, the resulting path coming from `/crisis-center/1`
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  would be `/crisis-center`.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/crisis-center/crisis-detail.component.1.ts (relative navigation)', 'relative-navigation')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  If we are using a `RouterLink` to navigate instead of the `Router` service, we can use the **same**
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  link parameters array, but we don't have to provide the object with the `relativeTo` property. The `ActivatedRoute`
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  is implicit in the `RouterLink` directive.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/crisis-center/crisis-list.component.1.ts (relative routerLink)', 'relative-navigation-router-link')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								<a id="guards"></a>
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								.l-main-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								h2#guards Route Guards
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  ## Milestone #4: Route Guards
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  At the moment, *any* user can navigate *anywhere* in the application *anytime*.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  That's not always the right thing to do.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * Perhaps the user is not authorized to navigate to the target component.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * Maybe the user must login (*authenticate*) first.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * Maybe we should fetch some data before we display the target component.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * We might want to save pending changes before leaving a component.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * We might ask the user if it's OK to discard pending changes rather than save them.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We can add ***guards*** to our route configuration to handle these scenarios.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  A guard's return value controls the router's behavior:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * if it returns `true`, the navigation process continues
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * if it returns `false`, the navigation process stops and the user stays put
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    The guard can also tell the router to navigate elsewhere, effectively canceling the current navigation.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-06-17 22:55:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  The guard *might* return its boolean answer synchronously.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  But in many cases, the guard can't produce an answer synchronously.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The guard could ask the user a question, save changes to the server, or fetch fresh data.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  These are all asynchronous operations.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Accordingly, a routing guard can return an `Observable<boolean>` or a `Promise<boolean>` and the
							 
						 
					
						
							
								
									
										
										
										
											2016-06-17 23:51:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  router will wait for the observable to resolve to `true` or `false`.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  The router supports multiple kinds of guards:
							 
						 
					
						
							
								
									
										
										
										
											2016-06-17 22:55:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  1. [CanActivate](../api/router/index/CanActivate-interface.html) to mediate navigation *to* a route.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  2. [CanActivateChild](../api/router/index/CanActivateChild-interface.html) to mediate navigation *to* a child route.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  3. [CanDeactivate](../api/router/index/CanDeactivate-interface.html) to mediate navigation *away* from the current route.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  4. [Resolve](../api/router/index/Resolve-interface.html) to perform route data retrieval *before* route activation.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  5. [CanLoad](../api/router/index/CanLoad-interface.html) to mediate navigation *to* a feature module loaded _asynchronously_.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We can have multiple guards at every level of a routing hierarchy.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  The router checks the `CanDeactivate` and `CanActivateChild` guards first, from deepest child route to the top.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Then it checks the `CanActivate` guards from the top down to the deepest child route. If the feature module
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  is loaded asynchronously, the `CanLoad` guard is checked before the module is loaded.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-17 22:55:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  If _any_ guard returns false, pending guards that have not completed will be canceled,
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  and the entire navigation is canceled.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Let's look at some examples.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								a#can-activate-guard
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  ### *CanActivate*: requiring authentication
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Applications often restrict access to a feature area based on who the user is.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We could permit access only to authenticated users or to users with a specific role.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We might block or limit access until the user's account is activated.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The `CanActivate` guard is the tool to manage these navigation business rules.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  #### Add an admin feature module
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We intend to extend the Crisis Center with some new *administrative* features.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Those features aren't defined yet. So we add a new feature module named `AdminModule`.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We'll follow our same convention by creating an `admin` folder with a feature
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  module file, route file and supporting components.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Our admin feature module file structure looks like this:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.filetree
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  .file app/admin
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  .children
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    .file admin-dashboard.component.ts
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    .file admin.component.ts
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    .file admin.module.ts
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    .file admin.routing.ts
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    .file manage-crises.component.ts
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    .file manage-heroes.component.ts
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Our admin feature module contains our `AdminComponent` used for routing within our
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  feature module, a dashboard route and two unfinished components to manage crises and heroes.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeTabs(
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   `router/ts/app/admin/admin-dashboard.component.1.ts,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   router/ts/app/admin/admin.component.ts,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   router/ts/app/admin/admin.module.ts,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   router/ts/app/admin/manage-crises.component.ts,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   router/ts/app/admin/manage-heroes.component.ts
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  `,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  null,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   `app/admin/admin-dashboard.component.ts,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   app/admin/admin.component.ts,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   app/admin/admin.module.ts,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   app/admin/manage-crises.component.ts,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   app/admin/manage-heroes.component.ts
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  `)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Since our admin dashboard `RouterLink` is an empty path route in our `AdminModule`, it
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    is considered a match to any route within our admin feature area. We only want the `Dashboard`
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    link to be active when we visit that route. We've added an additional binding to our `Dashboard` routerLink,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    `[routerLinkActiveOptions]="{ exact: true }"` which will only mark the `./` link as active when
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    we navigate the to `/admin` URL and not when we navigate to one the other child routes.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Our initial admin routing configuration:
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								+makeExcerpt('app/admin/admin.routing.1.ts (admin routing)', 'admin-routes')
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								h3#component-less-route <i>Component-Less Route</i>: grouping routes without a component
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Looking at our child route under the `AdminComponent`, we have a route with a **path** and a **children**
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  property but it's not using a **component**. We haven't made a mistake in our configuration, because we can
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  use a **component-less** route.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We want to group our `Crisis Center` management routes under the `admin` path, but we don't need a component
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  just to group those routes under an additional `RouterOutlet`. This also allows us to [guard child routes](#can-activate-child-guard).
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Next, we'll import the `AdminModule` into our `app.module.ts` and add it to the `imports` array
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  to register our admin routes.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/app.module.3.ts (admin module)', 'admin-module')
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  And we add a link to the `AppComponent` shell that users can click to get to this feature.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/app.component.4.ts', 'template')
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  #### Guard the admin feature
							 
						 
					
						
							
								
									
										
										
										
											2016-06-17 22:55:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Currently every route within our *Crisis Center* is open to everyone.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  The new *admin* feature should be accessible only to authenticated users.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-17 22:55:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We could hide the link until the user logs in. But that's tricky and difficult to maintain.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Instead we'll write a `CanActivate` guard to redirect anonymous users to the login page when they try to reach the admin component.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-17 22:55:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  This is a general purpose guard — we can imagine other features that require authenticated users —
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  so we create an `auth-guard.service.ts` in the application root folder.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-17 22:55:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  At the moment we're interested in seeing how guards work so our first version does nothing useful.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  It simply logs to console and `returns` true immediately, allowing navigation to proceed:
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/auth-guard.service.1.ts')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Next we open `admin.routing.ts `, import the `AuthGuard` class, and
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  update the admin route with a `CanActivate` guard property that references it:
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								+makeExcerpt('app/admin/admin.routing.2.ts (guarded admin route)', 'admin-route')
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Our admin feature is now protected by the guard, albeit protected poorly.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  #### Teach *AuthGuard* to authenticate
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Let's make our `AuthGuard` at least pretend to authenticate.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The `AuthGuard` should call an application service that can login a user and retain information about the current user.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Here's a demo `AuthService`:
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/auth.service.ts')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-06-17 22:55:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Although it doesn't actually log in, it has what we need for this discussion.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  It has an `isLoggedIn` flag to tell us whether the user is authenticated.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Its `login` method simulates an API call to an external service by returning an observable that resolves successfully after a short pause.
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  The `redirectUrl` property will store our attempted URL so we can navigate to it after authenticating.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Let's revise our `AuthGuard` to call it.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/auth-guard.service.2.ts (v2)', '')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-06-17 22:55:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Notice that we *inject* the `AuthService` and the `Router` in the constructor.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We haven't provided the `AuthService` yet but it's good to know that we can inject helpful services into our routing guards.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-17 22:55:36 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  This guard returns a synchronous boolean result.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  If the user is logged in, it returns true and the navigation continues.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  The `ActivatedRouteSnapshot` contains the _future_ route that will be activated and the `RouterStateSnapshot`
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  contains the _future_ `RouterState` of our application, should we pass through our guard check.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  If the user is not logged in, we store the attempted URL the user came from using the `RouterStateSnapshot.url` and
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  tell the router to navigate to a login page — a page we haven't created yet.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  This secondary navigation automatically cancels the current navigation; we return `false` just to be clear about that.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  #### Add the *LoginComponent*
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We need a `LoginComponent` for the user to log in to the app. After logging in, we'll redirect
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  to our stored URL if available, or use the default URL.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  There is nothing new about this component or the way we wire it into the router configuration.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We'll register a `/login` route in our `app.routing.ts` and add the necessary providers to the `appRoutingProviders`
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  array we created earlier. In our `app.module.ts`, we'll import the `LoginComponent` and add it to our `AppModule` `declarations`.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								+makeTabs(
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								   `router/ts/app/app.module.ts,
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								   router/ts/app/app.routing.6.ts,
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								   router/ts/app/login.component.1.ts,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   router/ts/app/login.routing.ts
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  `,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  null,
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								   `app/app.module.ts,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   app/app.routing.ts,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   app/login.component.ts,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   app/login.routing.ts
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  `)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Guards and the service providers they require **must** be provided at the module-level. This allows
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    the Router access to retrieve these services from the `Injector` during the navigation process.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    The same rule applies for feature modules loaded [asynchronously](#asynchronous-routing).
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								h3#can-activate-child-guard <i>CanActivateChild</i>: guarding child routes
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  As we learned about guarding routes with `CanActivate`, we can also protect child routes with the `CanActivateChild`
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  guard. The `CanActivateChild` guard works similarly to the `CanActivate` guard, but the difference is its run _before_
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  each child route is activated. We protected our admin feature module from unauthorized access, but we could also
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  protect child routes within our feature module.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Let's extend our `AuthGuard` to protect when navigating between our `admin` routes. First we'll open our
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  `auth-guard.service.ts` and add `CanActivateChild` interface to our imported tokens from the router package.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Next, we'll implement the `canActivateChild` method with takes the same arguments as the `canActivate` method,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  an `ActivatedRouteSnapshot` and `RouterStateSnapshot`. The `canActivateChild` behaves the same way the other
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  guards do, returning an `Observable<boolean>` or `Promise<boolean>` for async checks and `boolean` for sync checks.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We'll return a `boolean`
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/auth-guard.service.3.ts (excerpt)', 'can-activate-child')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We add the same `AuthGuard` to our `component-less` admin route to protect all other child routes at one time
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  instead of adding the `AuthGuard` to each route individually.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/admin/admin.routing.3.ts (excerpt)', 'can-activate-child')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								h3#can-deactivate-guard <i>CanDeactivate</i>: handling unsaved changes
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Back in the "Heroes" workflow, the app accepts every change to a hero immediately without hesitation or validation.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  In the real world, we might have to accumulate the users changes.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We might have to validate across fields. We might have to validate on the server.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We might have to hold changes in a pending state until the user confirms them *as a group* or
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  cancels and reverts all changes.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  What do we do about unapproved, unsaved changes when the user navigates away?
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We can't just leave and risk losing the user's changes; that would be a terrible experience.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We'd like to pause and let the user decide what to do.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  If the user cancels, we'll stay put and allow more changes.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  If the user approves, the app can save.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We still might delay navigation until the save succeeds.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  If we let the user move to the next screen immediately and
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  the save failed (perhaps the data are ruled invalid), we would have lost the context of the error.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We can't block while waiting for the server — that's not possible in a browser.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We need to stop the navigation while we wait, asynchronously, for the server
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  to return with its answer.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We need the `CanDeactivate` guard.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ### Cancel and Save
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Our sample application doesn't talk to a server.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Fortunately, we have another way to demonstrate an asynchronous router hook.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Users update crisis information in the `CrisisDetailComponent`.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Unlike the `HeroDetailComponent`, the user changes do not update the
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  crisis entity immediately. We update the entity when the user presses the *Save* button.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We discard the changes if the user presses he *Cancel* button.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Both buttons navigate back to the crisis list after save or cancel.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/crisis-center/crisis-detail.component.1.ts (excerpt)', 'cancel-save')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  What if the user tries to navigate away without saving or canceling?
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The user could push the browser back button or click the heroes link.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Both actions trigger a navigation.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Should the app save or cancel automatically?
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We'll do neither. Instead we'll ask the user to make that choice explicitly
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  in a confirmation dialog box that *waits asynchronously for the user's
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  answer*.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    We could wait for the user's answer with synchronous, blocking code.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Our app will be more responsive ... and can do other work ...
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    by waiting for the user's answer asynchronously. Waiting for the user asynchronously
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    is like waiting for the server asynchronously.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  The `DialogService` (provided in the `AppModule` for app-wide use) does the asking.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  It returns a [promise](http://exploringjs.com/es6/ch_promises.html) that
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  *resolves* when the user eventually decides what to do: either
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  to discard changes and navigate away (`true`) or to preserve the pending changes and stay in the crisis editor (`false`).
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								a#CanDeactivate
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We create a `Guard` that will check for the presence of a `canDeactivate` function in our component, in this
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  case being `CrisisDetailComponent`. We don't need to know the details of how our `CrisisDetailComponent` confirms deactivation.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  This makes our guard reusable, which is an easy win for us.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExample('app/can-deactivate-guard.service.ts')
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Alternatively, We could make a component-specific `CanDeactivate` guard for our `CrisisDetailComponent`. The `canDeactivate` method provides us
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  with the current instance of our `component`, the current `ActivatedRoute` and `RouterStateSnapshot` in case we needed to access
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  some external information. This would be useful if we only wanted to use this guard for this component and needed to ask the component's
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  properties in or to confirm whether the router should allow navigation away from it.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/can-deactivate-guard.service.1.ts (component-specific)', '')
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Looking back at our `CrisisDetailComponent`, we have implemented our confirmation workflow for unsaved changes.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								+makeExcerpt('app/crisis-center/crisis-detail.component.1.ts (excerpt)', 'cancel-save-only')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Notice that the `canDeactivate` method *can* return synchronously;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  it returns `true` immediately if there is no crisis or there are no pending changes.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  But it can also return a `Promise` or an `Observable` and the router will wait for that
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  to resolve to truthy (navigate) or falsey (stay put).
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We add the `Guard` to our crisis detail route in `crisis-center.routing.ts` using the `canDeactivate` array.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								+makeExcerpt('app/crisis-center/crisis-center.routing.3.ts (can deactivate guard)', '')
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We also need to add the `Guard` to our main `appRoutingProviders` so the `Router` can inject it during the navigation process.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								+makeExample('app/app.routing.6.ts', '', '')
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Now we have given our user a safeguard against unsaved changes.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								<a id="Resolve"></a>
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								h3#resolve-guard <i>Resolve</i>: pre-fetching component data
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  In our `Hero Detail` and `Crisis Detail`, we waited until the route was activated to fetch our respective hero or crisis.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  This worked well for us, but we can always do better.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  If we were using a real world api, there may be some delay in when the data we want to display gets returned.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We don't want to display a blank component until the data loads in this situation.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-14 15:46:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We'd like to pre-fetch data from the server so it's ready the moment our route is activated.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We'd also like to handle the situation where our data fails to load or some other error condition occurs.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  This would help us in our `Crisis Center` if we navigated to an `id` that doesn't return a record.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We could send the user back to the `Crisis List` where we only show valid crisis centers.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We want to delay rendering of our route component until all necessary data has been fetched or some action
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  has occurred.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We need the `Resolve` guard.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ### Preload route information
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We'll update our `Crisis Detail` route to resolve our Crisis before loading the route, or if the user happens to
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  navigate to an invalid crisis center `:id`, we'll navigate back to our list of existing crises.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Like the `CanActivate` and `CanDeactivate` guards, the **`Resolve`** guard is an interface we can implement as a service
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  to resolve route data synchronously or asynchronously. In `CrisisDetailComponent`, we used the `ngOnInit` to retrieve the `Crisis`
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  information. We also navigated the user away from the route if the `Crisis` was not found. It would be more efficient to perform this
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  action before the route is ever activated.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We'll create a `CrisisDetailResolve` service that will handle retrieving the `Crisis` and navigating the user away if the `Crisis` does
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  not exist. Then we can be assured that when we activate the `CrisisDetailComponent`, the associated Crisis will already be available
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  for display.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Let's create our `crisis-detail-resolve.service.ts` file within our `Crisis Center` feature area.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								+makeExample('app/crisis-center/crisis-detail-resolve.service.ts', '')
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We'll take the relevant parts of the `ngOnInit` lifecycle hook in our `CrisisDetailComponent` and moved them into our `CrisisDetailResolve` guard.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We import the `Crisis` model and `CrisisService` and also the `Router` for navigation from our resolve implementation. We want to be explicit about
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  the data we are resolving, so we implement the `Resolve` interface with a type of `Crisis`. This lets us know that what we will resolve will match our
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  `Crisis` model. We inject the `CrisisService` and `Router` and implement the `resolve` method that supports a `Promise`, `Observable` or a synchronous
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return value.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We'll use our `CrisisService.getCrisis` method that returns a promise to prevent our route from loading until the data is fetched. If we don't find a valid `Crisis`,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  we navigate the user back to the `CrisisList`, canceling the previous in-flight navigation to the crisis details.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Now that our guard is ready, we'll import it in our `crisis-center.routing.ts` and use the `resolve` object in our route configuration.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								+makeExcerpt('app/crisis-center/crisis-center.routing.ts (resolve)', 'crisis-detail-resolve')
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We'll add the `CrisisDetailResolve` service to our crisis center module's `providers`, so its available to the `Router` during the navigation process.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								+makeExcerpt('app/crisis-center/crisis-center.module.ts (crisis detail resolve provider)', 'crisis-detail-resolve')
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Now that we've added our `Resolve` guard to fetch data before the route loads, we no longer need to do this once we get into our `CrisisDetailComponent`.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We'll update the `CrisisDetailComponent` to use the `ActivatedRoute` data, which is where our `crisis` property from our `Resolve` guard will be provided.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Once activated, all we need to do is set our local `crisis` and `editName` properties from our resolved `Crisis` information. The `Crisis` is being provided
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  at the time the route component is activated.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								+makeExcerpt('app/crisis-center/crisis-detail.component.ts (ngOnInit v2)', 'crisis-detail-resolve')
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  **Two critical points**
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  1. The router interface is optional. We don't inherit from a base class. We simply implement the interface method or not.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  1. We rely on the router to call the guard. We don't worry about all the ways that the user
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  could navigate away. That's the router's job.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We simply write this class and let the router take it from there.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The relevant *Crisis Center* code for this milestone is
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeTabs(
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   `router/ts/app/app.component.ts,
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								   router/ts/app/crisis-center/crisis-center-home.component.ts,
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								   router/ts/app/crisis-center/crisis-center.component.ts,
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								   router/ts/app/crisis-center/crisis-center.routing.ts,
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								   router/ts/app/crisis-center/crisis-list.component.ts,
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								   router/ts/app/crisis-center/crisis-detail.component.ts,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   router/ts/app/crisis-center/crisis-detail-resolve.service.ts,
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								   router/ts/app/crisis-center/crisis.service.ts
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  `,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  null,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   `app.component.ts,
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								   crisis-center-home.component.ts,
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								   crisis-center.component.ts,
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								   crisis-center.routing.ts,
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								   crisis-list.component.ts,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   crisis-detail.component.ts,
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								   crisis-detail-resolve.service.ts,
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								   crisis.service.ts
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  `)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								+makeTabs(
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								   `router/ts/app/auth-guard.service.3.ts,
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								   router/ts/app/can-deactivate-guard.service.ts
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  `,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  null,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   `auth-guard.service.ts,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   can-deactivate-guard.service.ts
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  `)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								a#query-parameters
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								a#fragment
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  ### Query Parameters and Fragments
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  In our [route parameters](#optional-route-parameters) example, we only dealt with parameters specific to
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  our route, but what if we wanted optional parameters available to all routes? This is where our
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  query parameters come into play and serve a special purpose in our application.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  [Fragments](https://en.wikipedia.org/wiki/Fragment_identifier) refer to certain elements on the page
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  identified with an `id` attribute.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We'll update our `AuthGuard` to provide a `session_id` query that will remain after navigating to another route.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We'll also provide an arbitrary `anchor` fragment, which we would use to jump to a certain point on our page.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We'll add the `NavigationExtras` object to our `router.navigate` method that navigates us to our `/login` route.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								+makeExcerpt('app/auth-guard.service.4.ts (v3)', '')
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We can also **preserve** query parameters and fragments across navigations without having to re-provide them
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  when navigating. In our `LoginComponent`, we'll add an *object* as the second argument in our `router.navigate` function
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  and provide the `preserveQueryParams` and `preserveFragment` to pass along the current query parameters
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  and fragment to the next route.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								+makeExcerpt('app/login.component.ts', 'preserve')
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Since we'll be navigating to our *Admin Dashboard* route after logging in, we'll update it to handle our
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  query parameters and fragment.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								+makeExcerpt('app/admin/admin-dashboard.component.ts (v2)', '')
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  *Query Parameters* and *Fragments* are also available through the `ActivatedRoute` service available to route components.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Just like our *route parameters*, query parameters and fragments are provided as an `Observable`.
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  For our updated *Crisis Admin* component we'll feed the `Observable` directly into our template using the `AsyncPipe`, which
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  will handle _unsubscribing_ from the `Observable` for us when the component is destroyed.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  img(src='/resources/images/devguide/plunker-separate-window-button.png' alt="pop out the window" align="right" style="margin-right:-20px")
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    When running in plunker, pop out the preview window by clicking the blue 'X' button in the upper right corner.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Following the steps in this process, we can click on the *Admin* button, that takes us to the *Login*
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  page with our provided `query params` and `fragment`. After we click the login button, we notice that
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  we have been redirected to the `Admin Dashboard` page with our `query params` and `fragment` still intact. We can use
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  these persistent bits of information for things that need to be provided with across pages interaction like
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  authentication tokens or session ids.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    The `query params` and `fragment` can also be preserved using a `RouterLink` with
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    the **preserveQueryParams** and **preserveFragment** bindings respectively.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								<a id="asynchronous-routing"></a>
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.l-main-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ## Milestone #5: Asynchronous Routing
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  As we have completed our milestones, our application has naturally gotten larger. As we continue to build
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  out feature areas our overall application size will get larger also. At some point we'll reach a tipping
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  point in where our application takes a significant enough time to load. This is not a viable long term solution.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  So how do we combat this problem? We introduce asynchronous routing into our application and take advantage of loading
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  feature areas _lazily_. This buys us multiple things:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  * We can continue building out feature areas without increasing our initial bundle.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * We can load feature areas only when requested by the user.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * We can speed up load time for users that only visit certain areas of our application.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  These are all things we want to have in our application, so let's apply this to our current setup. We've already made
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  great strides by organizing our application into four modules: `AppModule`, `HeroesModule`, `AdminModule` and `CrisisCenterModule`.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Our `AdminModule` is the area of our application that would be scoped to a small set of users, so we'll take advantage
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  of asynchronous routing and only load the `Admin` feature area when requested.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ### Lazy-Loading route configuration
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We'll start by adding an `admin` route to our `app.routing.ts` file. We want to load our `Admin` module asynchronously,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  so we'll use the `loadChildren` property in our route config where previously we used the `children` property to include our child routes.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We'll also change our `admin` **path** in our `admin.routing.ts` to an empty path. The `Router` supports
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  *empty path* routes, which we can use for grouping routes together without adding anything additional paths to the URL. Our
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  users will still visit `/admin` and our `AdminComponent` still serves as our *Routing Component* which contains
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  our child routes.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeTabs(
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  `router/ts/app/app.routing.ts,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  router/ts/app/admin/admin.routing.ts`,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  'lazy-load-admin,',
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  `app.routing.ts (load children),
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  app/admin/admin.routing.ts (empty path admin)
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  `)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    We use the ES2015 `spread` feature to flatten the route arrays of our `adminRoutes` and `loginRoutes`
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    into our `appRoutes` array to provide a simple array of routes.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  The `loadChildren` property is used by the `Router` to map to our bundle we want to lazy-load, in this case being the `AdminModule`.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  If we look closer at the `loadChildren` string, we can see that it maps directly to our `admin.module.ts` file where we previously built
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  out our `Admin` feature area. After the path to the file we use a `#` to denote where our file path ends and to tell the `Router` the name
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  of our `AdminModule`. If we look in our `admin.module.ts` file, we can see it matches name of our exported module class.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								+makeExcerpt('app/admin/admin.module.ts (export)', 'admin-module-export')
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  The `loadChildren` property is used by the `Router` to map to our bundle we want to lazy-load, in this case being the `AdminModule`.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The router will take our loadChildren string and dynamically load in our `AdminModule`, add its routes to our configuration *dynamically*
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  and then load the requested route. This will only happen when the route is **first** requested and the module will be immediately be available
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  for subsequent requests.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Angular provides a built-in module loader that supports **`SystemJS`** to load modules asynchronously. If we were
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    using another bundling tool, such as **Webpack**, we would use the Webpack mechanism for asynchronously loading modules.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We've built our feature area, we've updated our route configuration to take advantage of lazy-loading, now we have to do the final step
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  to break our `AdminModule` into a completely separate module. In our `app.module.ts`, we'll remove our `AdminModule` from the
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  `imports` array since we'll be loading it on-demand an we'll remove the imported `AdminModule`.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								+makeExcerpt('app/app.module.ts (async admin module)', '')
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								h3#can-load-guard <i>CanLoad Guard</i>: guarding against loading of feature modules
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We're already protecting our `AdminModule` with a `CanActivate` guard that prevents the user from
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  accessing the admin feature area unless authorized. We're currently loading the admin routing
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  asynchronously when requested, checking the user access and redirecting to the login page if not
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  authorized. Ideally, we only want to load the `AdminModule` if the user is logged in and prevent
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  the `AdminModule` and its routing from being loaded until then.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The **CanLoad** guard covers this scenario.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We can use the `CanLoad` guard to only load the `AdminModule` once the user is logged in **and** attempts
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  to access the admin feature area. We'll update our existing `AuthGuard` to support the `CanLoad` guard. We'll import
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  the `CanLoad` interface and the `Route` the guard provides when called that contains the requested path.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We'll add the interface to our service, and then we'll implement the interface. Since our `AuthGuard` already
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  checks the user's logged in state, we can pass that access check to our `canLoad` method. The `Route` in
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  the `canLoad` method provides a **path** which comes from our route configuration.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/auth-guard.service.ts (can load guard)', '')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Next, we'll import the `AuthGuard` into our `app.routing.ts` and add the `AuthGuard` to the `canLoad` array for
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  our `admin` route. Now our `admin` feature area is only loaded when the proper access has been granted.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/app.routing.ts (can load guard)', 'can-load-guard')
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								<a id="final-app"></a>
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.l-main-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ## Wrap Up
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We've covered a lot of ground in this chapter and the application is too big to reprint here.
							 
						 
					
						
							
								
									
										
										
										
											2016-07-30 21:00:52 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Please visit the <live-example></live-example> and
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  where you can download the final source code.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.l-main-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ## Appendices
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The balance of this chapter is a set of appendices that
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  elaborate some of the points we covered quickly above.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The appendix material isn't essential. Continued reading is for the curious.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								.l-main-section#link-parameters-array
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ## Appendix: Link Parameters Array
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We've mentioned the *Link Parameters Array* several times. We've used it several times.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  A link parameters array holds the ingredients for router navigation:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * the *path* of the route to the destination component
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  * required and optional route parameters that go into the route URL
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We can bind the `RouterLink` directive to such an array like this:
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/app.component.3.ts', 'h-anchor', '')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We've written a two element array when specifying a route parameter like this
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/heroes/hero-list.component.1.ts', 'nav-to-detail', '')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  We can provide optional route parameters in an object like this:
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/app.component.3.ts', 'cc-query-params', '')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  These three examples cover our needs for an app with one level routing.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  The moment we add a child router, such as the *Crisis Center*, we create new link array possibilities.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Recall that we specified a default child route for *Crisis Center* so this simple `RouterLink` is fine.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/app.component.3.ts', 'cc-anchor-w-default', '')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Let's parse it out.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * The first item in the array identifies the parent route ('/crisis-center').
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * There are no parameters for this parent route so we're done with it.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * There is no default for the child route so we need to pick one.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * We decide to go to the `CrisisListComponent` whose route path is '/' but we don't need to explicitly add it
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * Voila! `['/crisis-center']`.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Let's take it a step further.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  This time we'll build a link parameters array that navigates from the root of the application
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  down to the "Dragon Crisis".
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * The first item in the array identifies the parent route ('/crisis-center').
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * There are no parameters for this parent route so we're done with it.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * The second item identifies the child route for details about a particular crisis ('/:id').
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * The details child route requires an `id` route parameter
							 
						 
					
						
							
								
									
										
										
										
											2016-07-16 17:34:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  * We add `id` of the *Dragon Crisis* as the second item in the array (`1`)
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  It looks like this!
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/app.component.3.ts', 'Dragon-anchor', '')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  If we wanted to, we could redefine our `AppComponent` template with *Crisis Center* routes exclusively:
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('app/app.component.3.ts', 'template', '')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  In sum, we can write applications with one, two or more levels of routing.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The link parameters array affords the flexibility to represent any routing depth and
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  any legal sequence of route paths, (required) router parameters and (optional) route parameter objects.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								.l-main-section#onInit
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ## Appendix: Why use an *ngOnInit* method
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We implemented an `ngOnInit` method in many of our Component classes.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We did so, for example, in the [HeroDetailComponent](#hero-detail-ctor).
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We might have put the `ngOnInit` logic inside the constructor instead. We didn't for a reason. The reason is *testability*.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  A constructor that has major side-effects can be difficult to test because it starts doing things as soon as
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  we create a test instance. In this case, it might have made a request to a remote server, something it shouldn't
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  do under test. It may even be impossible to reach the server in the test environment.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The better practice is to limit what the constructor can do. Mostly it should stash parameters in
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  local variables and perform simple instance configuration.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Yet we want an instance of this class to get the hero data from the `HeroService` soon after it is created.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  How do we ensure that happens if not in the constructor?
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Angular detects when a component has certain lifecycle methods like
							 
						 
					
						
							
								
									
										
										
										
											2016-06-21 22:22:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  [ngOnInit](../api/core/index/OnInit-class.html) and
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  [ngOnDestroy](../api/core/index/OnDestroy-class.html) and calls
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  them
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  at the appropriate moment.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Angular will call `ngOnInit` when we navigate to the `HeroDetailComponent`, we'll get the `id` from the `ActivatedRoute`
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  params and ask the server for the hero with that `id`.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We too can call that `ngOnInit` method in our tests if we wish ... after taking control of the injected
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  `HeroService` and (perhaps) mocking it.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-07 16:48:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								a#browser-url-styles
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.l-main-section#location-strategy
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ## Appendix: *LocationStrategy* and browser URL styles
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  When the router navigates to a new component view, it updates the browser's location and history
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  with a URL for that view.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  This is a strictly local URL. The browser shouldn't send this URL to the server
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  and should not reload the page.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Modern HTML 5 browsers support
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  [history.pushState](https://developer.mozilla.org/en-US/docs/Web/API/History_API#Adding_and_modifying_history_entries),
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  a technique that changes a browser's location and history without triggering a server page request.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The router can compose a "natural" URL that is indistinguishable from
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  one that would otherwise require a page load.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Here's the *Crisis Center* URL in this "HTML 5 pushState" style:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								code-example(format=".", language="bash").
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  localhost:3002/crisis-center/
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Older browsers send page requests to the server when the location URL changes ...
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  unless the change occurs after a "#" (called the "hash").
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Routers can take advantage of this exception by composing in-application route
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  URLs with hashes.  Here's a "hash URL" that routes to the *Crisis Center*
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								code-example(format=".", language="bash").
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  localhost:3002/src/#/crisis-center/
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  The Router supports both styles with two `LocationStrategy` providers:
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  1. `PathLocationStrategy` - the default "HTML 5 pushState" style.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  1. `HashLocationStrategy` - the "hash URL" style.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  The `RouterModule.forRoot` function sets the `LocationStrategy` to the `PathLocationStrategy`,
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  making it the default strategy.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We can switch to the `HashLocationStrategy` with an override during the bootstrapping process if we prefer it.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Learn about "providers" and the bootstrap process in the
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [Dependency Injection chapter](dependency-injection#bootstrap)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ### Which Strategy is Best?
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We must choose a strategy and we need to make the right call early in the project.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  It won't be easy to change later once the application is in production
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  and there are lots of application URL references in the wild.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-20 05:24:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  Almost all Angular projects should use the default HTML 5 style.
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  It produces URLs that are easier for users to understand.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  And it preserves the option to do **server-side rendering** later.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Rendering critical pages on the server is a technique that can greatly improve
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  perceived responsiveness when the app first loads.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  An app that would otherwise take ten or more seconds to start
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  could be rendered on the server and delivered to the user's device
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  in less than a second.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  This option is only available if application URLs look like normal web URLs
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  without hashes (#) in the middle.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Stick with the default unless you have a compelling reason to
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  resort to hash routes.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ### HTML 5 URLs and the  *<base href>*
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  While the router uses the "[HTML 5 pushState](https://developer.mozilla.org/en-US/docs/Web/API/History_API#Adding_and_modifying_history_entries)"
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  style by default, we *must* configure that strategy with a **base href**
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The preferred way to configure the strategy is to add a
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  [<base href> element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base) tag
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  in the `<head>` of the `index.html`.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								+makeExcerpt('index.1.html', 'base-href', '')
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Without that tag, the browser may not be able to load resources
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  (images, css, scripts) when "deep linking" into the app.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Bad things could happen when someone pastes an application link into the
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  browser's address bar or clicks such a link in an email link.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Some developers may not be able to add the `<base>` element, perhaps because they don't have
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  access to `<head>` or the `index.html`.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Those developers may still use HTML 5 URLs by taking two remedial steps:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  1. Provide the router with an appropriate `APP_BASE_HREF` value.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  1. Use **absolute URLs** for all web resources: css, images, scripts, and template html files.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								.l-sub-section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  :marked
							 
						 
					
						
							
								
									
										
										
										
											2016-06-27 12:57:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Learn about the [APP_BASE_HREF](../api/common/index/APP_BASE_HREF-let.html)
							 
						 
					
						
							
								
									
										
										
										
											2016-06-09 13:00:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    in the API Guide.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								:marked
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ### *HashLocationStrategy*
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  We can go old-school with the `HashLocationStrategy` by
							 
						 
					
						
							
								
									
										
										
										
											2016-08-09 17:38:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  providing the `useHash: true` in an object as the second argument of the `RouterModule.forRoot`
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  in our `AppModule`.
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 11:20:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 23:19:27 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								+makeExcerpt('app/app.module.5.ts (hash URL strategy)', '')