` for async checks and a `boolean` for sync checks.
This one returns a `boolean`:
Add the same `AuthGuard` to the `component-less` admin route to protect all other child routes at one time
instead of adding the `AuthGuard` to each route individually.
{@a can-deactivate-guard}
### `CanDeactivate`: handling unsaved changes
Back in the "Heroes" workflow, the app accepts every change to a hero immediately without validation.
In the real world, you might have to accumulate the users changes, validate across fields, validate on the server, or hold changes in a pending state until the user confirms them as a group or cancels and reverts all changes.
When the user navigates away, you can let the user decide what to do with unsaved changes.
If the user cancels, you'll stay put and allow more changes.
If the user approves, the app can save.
You still might delay navigation until the save succeeds.
If you let the user move to the next screen immediately and saving were to fail (perhaps the data is ruled invalid), you would lose the context of the error.
You need to stop the navigation while you wait, asynchronously, for the server to return with its answer.
The `CanDeactivate` guard helps you decide what to do with unsaved changes and how to proceed.
{@a cancel-save}
#### Cancel and save
Users update crisis information in the `CrisisDetailComponent`.
Unlike the `HeroDetailComponent`, the user changes do not update the crisis entity immediately.
Instead, the app updates the entity when the user presses the Save button and discards the changes when the user presses the Cancel button.
Both buttons navigate back to the crisis list after save or cancel.
In this scenario, the user could click the heroes link, cancel, push the browser back button, or navigate away without saving.
This example app asks the user to be explicit with a confirmation dialog box that waits asynchronously for the user's
response.
You could wait for the user's answer with synchronous, blocking code, however, the app is more responsive—and can do other work—by waiting for the user's answer asynchronously.
Generate a `Dialog` service to handle user confirmation.
ng generate service dialog
Add a `confirm()` method to the `DialogService` to prompt the user to confirm their intent.
The `window.confirm` is a blocking action that displays a modal dialog and waits for user interaction.
It returns an `Observable` 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`).
{@a CanDeactivate}
Generate a guard that checks for the presence of a `canDeactivate()` method in a component—any component.
ng generate guard can-deactivate
Paste the following code into your guard.
While the guard doesn't have to know which component has a deactivate method, it can detect that the `CrisisDetailComponent` component has the `canDeactivate()` method and call it.
The guard not knowing the details of any component's deactivation method makes the guard reusable.
Alternatively, you could make a component-specific `CanDeactivate` guard for the `CrisisDetailComponent`.
The `canDeactivate()` method provides you with the current instance of the `component`, the current `ActivatedRoute`, and `RouterStateSnapshot` in case you needed to access some external information.
This would be useful if you only wanted to use this guard for this component and needed to get the component's properties or confirm whether the router should allow navigation away from it.
Looking back at the `CrisisDetailComponent`, it implements the confirmation workflow for unsaved changes.
Notice that the `canDeactivate()` method can return synchronously; it returns `true` immediately if there is no crisis or there are no pending changes.
But it can also return a `Promise` or an `Observable` and the router will wait for that to resolve to truthy (navigate) or falsy (stay on the current route).
Add the `Guard` to the crisis detail route in `crisis-center-routing.module.ts` using the `canDeactivate` array property.
Now you have given the user a safeguard against unsaved changes.
{@a Resolve}
{@a resolve-guard}
### _Resolve_: pre-fetching component data
In the `Hero Detail` and `Crisis Detail`, the app waited until the route was activated to fetch the respective hero or crisis.
If you were using a real world API, there might be some delay before the data to display is returned from the server.
You don't want to display a blank component while waiting for the data.
To improve this behavior, you can pre-fetch data from the server using a resolver so it's ready the
moment the route is activated.
This also allows you to handle errors before routing to the component.
There's no point in navigating to a crisis detail for an `id` that doesn't have a record.
It'd be better to send the user back to the `Crisis List` that shows only valid crisis centers.
In summary, you want to delay rendering the routed component until all necessary data has been fetched.
{@a fetch-before-navigating}
#### Fetch data before navigating
At the moment, the `CrisisDetailComponent` retrieves the selected crisis.
If the crisis is not found, the router navigates back to the crisis list view.
The experience might be better if all of this were handled first, before the route is activated.
A `CrisisDetailResolver` service could retrieve a `Crisis` or navigate away, if the `Crisis` did not exist, _before_ activating the route and creating the `CrisisDetailComponent`.
Generate a `CrisisDetailResolver` service file within the `Crisis Center` feature area.
ng generate service crisis-center/crisis-detail-resolver
Move the relevant parts of the crisis retrieval logic in `CrisisDetailComponent.ngOnInit()` into the `CrisisDetailResolverService`.
Import the `Crisis` model, `CrisisService`, and the `Router` so you can navigate elsewhere if you can't fetch the crisis.
Be explicit and implement the `Resolve` interface with a type of `Crisis`.
Inject the `CrisisService` and `Router` and implement the `resolve()` method.
That method could return a `Promise`, an `Observable`, or a synchronous return value.
The `CrisisService.getCrisis()` method returns an observable in order to prevent the route from loading until the data is fetched.
The `Router` guards require an observable to `complete`, which means it has emitted all
of its values.
You use the `take` operator with an argument of `1` to ensure that the `Observable` completes after retrieving the first value from the Observable returned by the `getCrisis()` method.
If it doesn't return a valid `Crisis`, then return an empty `Observable`, cancel the previous in-progress navigation to the `CrisisDetailComponent`, and navigate the user back to the `CrisisListComponent`.
The updated resolver service looks like this:
Import this resolver in the `crisis-center-routing.module.ts` and add a `resolve` object to the `CrisisDetailComponent` route configuration.
The `CrisisDetailComponent` should no longer fetch the crisis.
When you re-configured the route, you changed where the crisis is.
Update the `CrisisDetailComponent` to get the crisis from the `ActivatedRoute.data.crisis` property instead;
Note the following two important points:
1. The router's `Resolve` interface is optional.
The `CrisisDetailResolverService` doesn't inherit from a base class.
The router looks for that method and calls it if found.
1. The router calls the resolver in any case where the the user could navigate away so you don't have to code for each use case.
The relevant Crisis Center code for this milestone follows.
Guards
{@a query-parameters}
{@a fragment}
### Query parameters and fragments
In the [route parameters](#optional-route-parameters) section, you only dealt with parameters specific to the route.
However, you can use query parameters to get optional parameters available to all routes.
[Fragments](https://en.wikipedia.org/wiki/Fragment_identifier) refer to certain elements on the page
identified with an `id` attribute.
Update the `AuthGuard` to provide a `session_id` query that will remain after navigating to another route.
Add an `anchor` element so you can jump to a certain point on the page.
Add the `NavigationExtras` object to the `router.navigate()` method that navigates you to the `/login` route.
You can also preserve query parameters and fragments across navigations without having to provide them again when navigating.
In the `LoginComponent`, you'll add an *object* as the second argument in the `router.navigateUrl()` function and provide the `queryParamsHandling` and `preserveFragment` to pass along the current query parameters and fragment to the next route.
The `queryParamsHandling` feature also provides a `merge` option, which preserves and combines the current query parameters with any provided query parameters when navigating.
To navigate to the Admin Dashboard route after logging in, update `admin-dashboard.component.ts` to handle the
query parameters and fragment.
Query parameters and fragments are also available through the `ActivatedRoute` service.
Just like route parameters, the query parameters and fragments are provided as an `Observable`.
The updated Crisis Admin component feeds the `Observable` directly into the template using the `AsyncPipe`.
Now, you can click on the Admin button, which takes you to the Login page with the provided `queryParamMap` and `fragment`.
After you click the login button, notice that you have been redirected to the `Admin Dashboard` page with the query parameters and fragment still intact in the address bar.
You can use these persistent bits of information for things that need to be provided across pages like authentication tokens or session ids.
The `query params` and `fragment` can also be preserved using a `RouterLink` with
the `queryParamsHandling` and `preserveFragment` bindings respectively.
{@a asynchronous-routing}
## Milestone 6: Asynchronous routing
As you've worked through the milestones, the application has naturally gotten larger.
At some point you'll reach a point where the application takes a long time to load.
To remedy this issue, use asynchronous routing, which loads feature modules lazily, on request.
Lazy loading has multiple benefits.
* You can load feature areas only when requested by the user.
* You can speed up load time for users that only visit certain areas of the application.
* You can continue expanding lazy loaded feature areas without increasing the size of the initial load bundle.
You're already part of the way there.
By organizing the application into modules—`AppModule`,
`HeroesModule`, `AdminModule` and `CrisisCenterModule`—you
have natural candidates for lazy loading.
Some modules, like `AppModule`, must be loaded from the start.
But others can and should be lazy loaded.
The `AdminModule`, for example, is needed by a few authorized users, so
you should only load it when requested by the right people.
{@a lazy-loading-route-config}
### Lazy Loading route configuration
Change the `admin` path in the `admin-routing.module.ts` from `'admin'` to an empty string, `''`, the empty path.
Use empty path routes to group routes together without adding any additional path segments to the URL.
Users will still visit `/admin` and the `AdminComponent` still serves as the Routing Component containing child routes.
Open the `AppRoutingModule` and add a new `admin` route to its `appRoutes` array.
Give it a `loadChildren` property instead of a `children` property.
The `loadChildren` property takes a function that returns a promise using the browser's built-in syntax for lazy loading code using dynamic imports `import('...')`.
The path is the location of the `AdminModule` (relative to the app root).
After the code is requested and loaded, the `Promise` resolves an object that contains the `NgModule`, in this case the `AdminModule`.
*Note*: When using absolute paths, the `NgModule` file location must begin with `src/app` in order to resolve correctly. For custom [path mapping with absolute paths](https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping), you must configure the `baseUrl` and `paths` properties in the project `tsconfig.json`.
When the router navigates to this route, it uses the `loadChildren` string to dynamically load the `AdminModule`.
Then it adds the `AdminModule` routes to its current route configuration.
Finally, it loads the requested route to the destination admin component.
The lazy loading and re-configuration happen just once, when the route is first requested; the module and routes are available immediately for subsequent requests.
Angular provides a built-in module loader that supports SystemJS to load modules asynchronously. If you were
using another bundling tool, such as Webpack, you would use the Webpack mechanism for asynchronously loading modules.
Take the final step and detach the admin feature set from the main application.
The root `AppModule` must neither load nor reference the `AdminModule` or its files.
In `app.module.ts`, remove the `AdminModule` import statement from the top of the file
and remove the `AdminModule` from the NgModule's `imports` array.
{@a can-load-guard}
### `CanLoad`: guarding unauthorized loading of feature modules
You're already protecting the `AdminModule` with a `CanActivate` guard that prevents unauthorized users from accessing the admin feature area.
It redirects to the login page if the user is not authorized.
But the router is still loading the `AdminModule` even if the user can't visit any of its components.
Ideally, you'd only load the `AdminModule` if the user is logged in.
Add a `CanLoad` guard that only loads the `AdminModule` once the user is logged in _and_ attempts to access the admin feature area.
The existing `AuthGuard` already has the essential logic in its `checkLogin()` method to support the `CanLoad` guard.
Open `auth.guard.ts`.
Import the `CanLoad` interface from `@angular/router`.
Add it to the `AuthGuard` class's `implements` list.
Then implement `canLoad()` as follows:
The router sets the `canLoad()` method's `route` parameter to the intended destination URL.
The `checkLogin()` method redirects to that URL once the user has logged in.
Now import the `AuthGuard` into the `AppRoutingModule` and add the `AuthGuard` to the `canLoad`
array property for the `admin` route.
The completed admin route looks like this:
{@a preloading}
### Preloading: background loading of feature areas
In addition to loading modules on-demand, you can load modules asynchronously with preloading.
The `AppModule` is eagerly loaded when the application starts, meaning that it loads right away.
Now the `AdminModule` loads only when the user clicks on a link, which is called lazy loading.
Preloading allows you to load modules in the background so that the data is ready to render when the user activates a particular route.
Consider the Crisis Center.
It isn't the first view that a user sees.
By default, the Heroes are the first view.
For the smallest initial payload and fastest launch time, you should eagerly load the `AppModule` and the `HeroesModule`.
You could lazy load the Crisis Center.
But you're almost certain that the user will visit the Crisis Center within minutes of launching the app.
Ideally, the app would launch with just the `AppModule` and the `HeroesModule` loaded and then, almost immediately, load the `CrisisCenterModule` in the background.
By the time the user navigates to the Crisis Center, its module will have been loaded and ready.
{@a how-preloading}
#### How preloading works
After each successful navigation, the router looks in its configuration for an unloaded module that it can preload.
Whether it preloads a module, and which modules it preloads, depends upon the preload strategy.
The `Router` offers two preloading strategies:
* No preloading, which is the default. Lazy loaded feature areas are still loaded on-demand.
* Preloading of all lazy loaded feature areas.
The router either never preloads, or preloads every lazy loaded module.
The `Router` also supports [custom preloading strategies](#custom-preloading) for fine control over which modules to preload and when.
This section guides you through updating the `CrisisCenterModule` to load lazily by default and use the `PreloadAllModules` strategy to load all lazy loaded modules.
{@a lazy-load-crisis-center}
#### Lazy load the crisis center
Update the route configuration to lazy load the `CrisisCenterModule`.
Take the same steps you used to configure `AdminModule` for lazy loading.
1. Change the `crisis-center` path in the `CrisisCenterRoutingModule` to an empty string.
1. Add a `crisis-center` route to the `AppRoutingModule`.
1. Set the `loadChildren` string to load the `CrisisCenterModule`.
1. Remove all mention of the `CrisisCenterModule` from `app.module.ts`.
Here are the updated modules _before enabling preload_:
You could try this now and confirm that the `CrisisCenterModule` loads after you click the "Crisis Center" button.
To enable preloading of all lazy loaded modules, import the `PreloadAllModules` token from the Angular router package.
The second argument in the `RouterModule.forRoot()` method takes an object for additional configuration options.
The `preloadingStrategy` is one of those options.
Add the `PreloadAllModules` token to the `forRoot()` call:
This configures the `Router` preloader to immediately load all lazy loaded routes (routes with a `loadChildren` property).
When you visit `http://localhost:4200`, the `/heroes` route loads immediately upon launch and the router starts loading the `CrisisCenterModule` right after the `HeroesModule` loads.
Currently, the `AdminModule` does not preload because `CanLoad` is blocking it.
{@a preload-canload}
#### `CanLoad` blocks preload
The `PreloadAllModules` strategy does not load feature areas protected by a [CanLoad](#can-load-guard) guard.
You added a `CanLoad` guard to the route in the `AdminModule` a few steps back to block loading of that module until the user is authorized.
That `CanLoad` guard takes precedence over the preload strategy.
If you want to preload a module as well as guard against unauthorized access, remove the `canLoad()` guard method and rely on the [canActivate()](#can-activate-guard) guard alone.
{@a custom-preloading}
### Custom Preloading Strategy
Preloading every lazy loaded module works well in many situations.
However, in consideration of things such as low bandwidth and user metrics, you can use a custom preloading strategy for specific feature modules.
This section guides you through adding a custom strategy that only preloads routes whose `data.preload` flag is set to `true`.
Recall that you can add anything to the `data` property of a route.
Set the `data.preload` flag in the `crisis-center` route in the `AppRoutingModule`.
Generate a new `SelectivePreloadingStrategy` service.
ng generate service selective-preloading-strategy
Replace the contents of `selective-preloading-strategy.service.ts` with the following:
`SelectivePreloadingStrategyService` implements the `PreloadingStrategy`, which has one method, `preload()`.
The router calls the `preload()` method with two arguments:
1. The route to consider.
1. A loader function that can load the routed module asynchronously.
An implementation of `preload` must return an `Observable`.
If the route does preload, it returns the observable returned by calling the loader function.
If the route does not preload, it returns an `Observable` of `null`.
In this sample, the `preload()` method loads the route if the route's `data.preload` flag is truthy.
As a side-effect, `SelectivePreloadingStrategyService` logs the `path` of a selected route in its public `preloadedModules` array.
Shortly, you'll extend the `AdminDashboardComponent` to inject this service and display its `preloadedModules` array.
But first, make a few changes to the `AppRoutingModule`.
1. Import `SelectivePreloadingStrategyService` into `AppRoutingModule`.
1. Replace the `PreloadAllModules` strategy in the call to `forRoot()` with this `SelectivePreloadingStrategyService`.
1. Add the `SelectivePreloadingStrategyService` strategy to the `AppRoutingModule` providers array so you can inject it elsewhere in the app.
Now edit the `AdminDashboardComponent` to display the log of preloaded routes.
1. Import the `SelectivePreloadingStrategyService`.
1. Inject it into the dashboard's constructor.
1. Update the template to display the strategy service's `preloadedModules` array.
Now the file is as follows:
Once the application loads the initial route, the `CrisisCenterModule` is preloaded.
Verify this by logging in to the `Admin` feature area and noting that the `crisis-center` is listed in the `Preloaded Modules`.
It also logs to the browser's console.
{@a redirect-advanced}
### Migrating URLs with redirects
You've setup the routes for navigating around your application and used navigation imperatively and declaratively.
But like any application, requirements change over time.
You've setup links and navigation to `/heroes` and `/hero/:id` from the `HeroListComponent` and `HeroDetailComponent` components.
If there were a requirement that links to `heroes` become `superheroes`, you would still want the previous URLs to navigate correctly.
You also don't want to update every link in your application, so redirects makes refactoring routes trivial.
{@a url-refactor}
#### Changing `/heroes` to `/superheroes`
This section guides you through migrating the `Hero` routes to new URLs.
The `Router` checks for redirects in your configuration before navigating, so each redirect is triggered when needed. To support this change, add redirects from the old routes to the new routes in the `heroes-routing.module`.
Notice two different types of redirects.
The first change is from `/heroes` to `/superheroes` without any parameters.
The second change is from `/hero/:id` to `/superhero/:id`, which includes the `:id` route parameter.
Router redirects also use powerful pattern-matching, so the `Router` inspects the URL and replaces route parameters in the `path` with their appropriate destination.
Previously, you navigated to a URL such as `/hero/15` with a route parameter `id` of `15`.
The `Router` also supports [query parameters](#query-parameters) and the [fragment](#fragment) when using redirects.
* When using absolute redirects, the `Router` will use the query parameters and the fragment from the `redirectTo` in the route config.
* When using relative redirects, the `Router` use the query params and the fragment from the source URL.
Currently, the empty path route redirects to `/heroes`, which redirects to `/superheroes`.
This won't work because the `Router` handles redirects once at each level of routing configuration.
This prevents chaining of redirects, which can lead to endless redirect loops.
Instead, update the empty path route in `app-routing.module.ts` to redirect to `/superheroes`.
A `routerLink` isn't tied to route configuration, so update the associated router links to remain active when the new route is active.
Update the `app.component.ts` template for the `/heroes` `routerLink`.
Update the `goToHeroes()` method in the `hero-detail.component.ts` to navigate back to `/superheroes` with the optional route parameters.
With the redirects setup, all previous routes now point to their new destinations and both URLs still function as intended.
{@a inspect-config}
### Inspect the router's configuration
To determine if your routes are actually evaluated [in the proper order](#routing-module-order), you can inspect the router's configuration.
Do this by injecting the router and logging to the console its `config` property.
For example, update the `AppModule` as follows and look in the browser console window
to see the finished route configuration.
{@a final-app}
## Final app
For the completed router app, see the for the final source code.
{@a link-parameters-array}
## Link parameters array
A link parameters array holds the following ingredients for router navigation:
* The path of the route to the destination component.
* Required and optional route parameters that go into the route URL.
You can bind the `RouterLink` directive to such an array like this:
The following is a two-element array when specifying a route parameter:
You can provide optional route parameters in an object, as in `{ foo: 'foo' }`:
These three examples cover the needs of an app with one level of routing.
However, with a child router, such as in the crisis center, you create new link array possibilities.
The following minimal `RouterLink` example builds upon a specified [default child route](guide/router#a-crisis-center-with-child-routes) for the crisis center.
Note the following:
* The first item in the array identifies the parent route (`/crisis-center`).
* There are no parameters for this parent route.
* There is no default for the child route so you need to pick one.
* You're navigating to the `CrisisListComponent`, whose route path is `/`, but you don't need to explicitly add the slash.
Consider the following router link 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.
* The second item identifies the child route details about a particular crisis (`/:id`).
* The details child route requires an `id` route parameter.
* You added the `id` of the Dragon Crisis as the second item in the array (`1`).
* The resulting path is `/crisis-center/1`.
You could also redefine the `AppComponent` template with Crisis Center routes exclusively:
In summary, you 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.
{@a browser-url-styles}
{@a location-strategy}
## `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.
As this is a strictly local URL the browser won't send this URL to the server and will not reload the page.
Modern HTML5 browsers support history.pushState, 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 "HTML5 pushState" style:
localhost:3002/crisis-center/
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.
localhost:3002/src/#/crisis-center/
The router supports both styles with two `LocationStrategy` providers:
1. `PathLocationStrategy`—the default "HTML5 pushState" style.
1. `HashLocationStrategy`—the "hash URL" style.
The `RouterModule.forRoot()` function sets the `LocationStrategy` to the `PathLocationStrategy`, which makes it the default strategy.
You also have the option of switching to the `HashLocationStrategy` with an override during the bootstrapping process.
For more information on providers and the bootstrap process, see [Dependency Injection](guide/dependency-injection#bootstrap).
## Choosing a routing strategy
You must choose a routing strategy early in the development of you project because once the application is in production, visitors to your site use and depend on application URL references.
Almost all Angular projects should use the default HTML5 style.
It produces URLs that are easier for users to understand and it preserves the option to do server-side rendering.
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.
## ``
The router uses the browser's history.pushState for navigation.
`pushState` allows you to customize in-app URL paths; for example, `localhost:4200/crisis-center`.
The in-app URLs can be indistinguishable from server URLs.
Modern HTML5 browsers were the first to support `pushState` which is why many people refer to these URLs as "HTML5 style" URLs.
HTML5 style navigation is the router default.
In the [LocationStrategy and browser URL styles](#browser-url-styles) section, learn why HTML5 style is preferable, how to adjust its behavior, and how to switch to the older hash (#) style, if necessary.
You must add a <base href> element to the app's `index.html` for `pushState` routing to work.
The browser uses the `` value to prefix relative URLs when referencing CSS files, scripts, and images.
Add the `` element just after the `` tag.
If the `app` folder is the application root, as it is for this application,
set the `href` value in `index.html` as shown here.
### HTML5 URLs and the ``
While the router uses the HTML5 pushState style by default, you must configure that strategy with a ``.
The preferred way to configure the strategy is to add a <base href> element tag in the `` of the `index.html`.
Without that tag, the browser may not be able to load resources
(images, CSS, scripts) when "deep linking" into the app.
Some developers may not be able to add the `` element, perhaps because they don't have access to `` or the `index.html`.
Those developers may still use HTML5 URLs by taking the following two steps:
1. Provide the router with an appropriate [APP_BASE_HREF][] value.
1. Use root URLs for all web resources: CSS, images, scripts, and template HTML files.
{@a hashlocationstrategy}
### `HashLocationStrategy`
You can use `HashLocationStrategy` by providing the `useHash: true` in an object as the second argument of the `RouterModule.forRoot()` in the `AppModule`.
## Router Reference
The folllowing sections highlight some core router concepts.
{@a basics-router-imports}
### Router imports
The Angular Router is an optional service that presents a particular component view for a given URL.
It is not part of the Angular core and thus is in its own library package, `@angular/router`.
Import what you need from it as you would from any other Angular package.
For more on browser URL styles, see [`LocationStrategy` and browser URL styles](#browser-url-styles).
{@a basics-config}
### Configuration
A routed Angular application has one singleton instance of the `Router` service.
When the browser's URL changes, that router looks for a corresponding `Route` from which it can determine the component to display.
A router has no routes until you configure it.
The following example creates five route definitions, configures the router via the `RouterModule.forRoot()` method, and adds the result to the `AppModule`'s `imports` array.
{@a example-config}
The `appRoutes` array of routes describes how to navigate.
Pass it to the `RouterModule.forRoot()` method in the module `imports` to configure the router.
Each `Route` maps a URL `path` to a component.
There are no leading slashes in the path.
The router parses and builds the final URL for you, which allows you to use both relative and absolute paths when navigating between application views.
The `:id` in the second 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` uses that value to find and present the hero whose `id` is 42.
The `data` property in the third route is a place to store arbitrary data associated with
this specific route.
The data property is accessible within each activated route. Use it to store items such as page titles, breadcrumb text, and other read-only, static data.
You can use the [resolve guard](#resolve-guard) to retrieve dynamic data.
The empty path in the fourth route represents the default path for the application—the place to go when the path in the URL is empty, as it typically is at the start.
This default route redirects to the route for the `/heroes` URL and, therefore, displays the `HeroesListComponent`.
If you need to see what events are happening during the navigation lifecycle, there is the `enableTracing` option as part of the router's default configuration.
This outputs each router event that took place during each navigation lifecycle to the browser console.
Use `enableTracing` only for debugging purposes.
You set the `enableTracing: true` option in the object passed as the second argument to the `RouterModule.forRoot()` method.
{@a basics-router-outlet}
### Router outlet
The `RouterOutlet` is a directive from the router library that is used like a component.
It acts as a placeholder that marks the spot in the template where the router should
display the components for that outlet.
<router-outlet></router-outlet>
<!-- Routed components go here -->
Given the configuration above, when the browser URL for this application becomes `/heroes`, the router matches that URL to the route path `/heroes` and displays the `HeroListComponent` as a sibling element to the `RouterOutlet` that you've placed in the host component's template.
{@a basics-router-links}
{@a router-link}
### Router links
To navigate as a result of some user action such as the click of an anchor tag, use `RouterLink`.
Consider the following template:
The `RouterLink` directives on the anchor tags give the router control over those elements.
The navigation paths are fixed, so you can assign a string to the `routerLink` (a "one-time" binding).
Had the navigation path been more dynamic, you could have bound to a template expression that returned an array of route link parameters; that is, the [link parameters array](guide/router#link-parameters-array).
The router resolves that array into a complete URL.
{@a router-link-active}
### Active router links
The `RouterLinkActive` directive toggles CSS classes for active `RouterLink` bindings based on the current `RouterState`.
On each anchor tag, you see a [property binding](guide/template-syntax#property-binding) to the `RouterLinkActive` directive that looks like `routerLinkActive="..."`.
The template expression to the right of the equal sign, `=`, contains a space-delimited string of CSS classes that the Router adds when this link is active (and removes when the link is inactive).
You set the `RouterLinkActive` directive to a string of classes such as `[routerLinkActive]="'active fluffy'"` or bind it to a component property that returns such a string.
Active route links cascade down through each level of the route tree, so parent and child router links can be active at the same time.
To override this behavior, you 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.
{@a basics-router-state}
### Router state
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. You can access the current `RouterState` from anywhere in the application using the `Router` service and the `routerState` property.
Each `ActivatedRoute` in the `RouterState` provides methods to traverse up and down the route tree to get information from parent, child and sibling routes.
{@a activated-route}
### Activated route
The route path and parameters are available through an injected router service called the [ActivatedRoute](api/router/ActivatedRoute).
It has a great deal of useful information including:
Property
|
Description
|
url
|
An `Observable` of the route path(s), represented 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).
|
paramMap
|
An `Observable` that contains a [map](api/router/ParamMap) of the required and [optional parameters](#optional-route-parameters) specific to the route.
The map supports retrieving single and multiple values from the same parameter.
|
queryParamMap
|
An `Observable` that contains a [map](api/router/ParamMap) of the [query parameters](#query-parameters) available to all routes.
The map supports retrieving single and multiple values from the query parameter.
|
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
|
The route's parent `ActivatedRoute` when this route is a [child route](#child-routing-component).
|
firstChild
|
Contains the first `ActivatedRoute` in the list of this route's child routes.
|
children
|
Contains all the [child routes](#child-routing-component) activated under the current route.
|
Two older properties are still available, however, their replacements are preferable as they may be deprecated in a future Angular version.
* `params`: An `Observable` that contains the required and [optional parameters](#optional-route-parameters) specific to the route. Use `paramMap` instead.
* `queryParams`: An `Observable` that contains the [query parameters](#query-parameters) available to all routes.
Use `queryParamMap` instead.
### Router events
During each navigation, the `Router` emits navigation events through the `Router.events` property.
These events range from when the navigation starts and ends to many points in between. The full list of navigation events is displayed in the table below.
Router Event
|
Description
|
NavigationStart
|
An [event](api/router/NavigationStart) triggered when navigation starts.
|
RouteConfigLoadStart
|
An [event](api/router/RouteConfigLoadStart) triggered before the `Router`
[lazy loads](#asynchronous-routing) a route configuration.
|
RouteConfigLoadEnd
|
An [event](api/router/RouteConfigLoadEnd) triggered after a route has been lazy loaded.
|
RoutesRecognized
|
An [event](api/router/RoutesRecognized) triggered when the Router parses the URL and the routes are recognized.
|
GuardsCheckStart
|
An [event](api/router/GuardsCheckStart) triggered when the Router begins the Guards phase of routing.
|
ChildActivationStart
|
An [event](api/router/ChildActivationStart) triggered when the Router begins activating a route's children.
|
ActivationStart
|
An [event](api/router/ActivationStart) triggered when the Router begins activating a route.
|
GuardsCheckEnd
|
An [event](api/router/GuardsCheckEnd) triggered when the Router finishes the Guards phase of routing successfully.
|
ResolveStart
|
An [event](api/router/ResolveStart) triggered when the Router begins the Resolve phase of routing.
|
ResolveEnd
|
An [event](api/router/ResolveEnd) triggered when the Router finishes the Resolve phase of routing successfuly.
|
ChildActivationEnd
|
An [event](api/router/ChildActivationEnd) triggered when the Router finishes activating a route's children.
|
ActivationEnd
|
An [event](api/router/ActivationStart) triggered when the Router finishes activating a route.
|
NavigationEnd
|
An [event](api/router/NavigationEnd) triggered when navigation ends successfully.
|
NavigationCancel
|
An [event](api/router/NavigationCancel) triggered when navigation is canceled.
This can happen when a [Route Guard](#guards) returns false during navigation,
or redirects by returning a `UrlTree`.
|
NavigationError
|
An [event](api/router/NavigationError) triggered when navigation fails due to an unexpected error.
|
Scroll
|
An [event](api/router/Scroll) that represents a scrolling event.
|
When you enable the `enableTracing` option, Angular logs these events to the console.
For an example of filtering router navigation events, see the [router section](guide/observables-in-angular#router) of the [Observables in Angular](guide/observables-in-angular) guide.
### Router terminology
Here are the key `Router` terms and their meanings:
Router Part
|
Meaning
|
Router
|
Displays the application component for the active URL.
Manages navigation from one component to the next.
|
RouterModule
|
A separate NgModule that provides the necessary service providers
and directives for navigating through application views.
|
Routes
|
Defines an array of Routes, each mapping a URL path to a component.
|
Route
|
Defines how the router should navigate to a component based on a URL pattern.
Most routes consist of a path and a component type.
|
RouterOutlet
|
The directive (<router-outlet> ) that marks where the router displays a view.
|
RouterLink
|
The directive for binding a clickable HTML element to a route. Clicking an element with a routerLink directive that is bound to a string or a link parameters array triggers a navigation.
|
RouterLinkActive
|
The directive for adding/removing classes from an HTML element when an associated routerLink contained on or inside the element becomes active/inactive.
|
ActivatedRoute
|
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.
|
RouterState
|
The current state of the router including a tree of the currently activated routes together with convenience methods for traversing the route tree.
|
Link parameters array
|
An array that the router interprets as a routing instruction.
You can bind that array to a RouterLink or pass the array as an argument to the Router.navigate method.
|
Routing component
|
An Angular component with a RouterOutlet that displays views based on router navigations.
|