Router

About

routing/common-router-tasks
routing/activated-route

Tipically the routes will be inside a file app.routes.ts.

Routes order is important since Router uses a first-match wins strategy.

  • More specific routes should be placed above less specific (more generic) routes.

  • Place wildcard ** routes last.

<router-outlet>

The router Directive to indicate the place where the Angular router will load the Component of the currently selected route.

It can be used with Absolute paths or Relative paths.

  • Absolute paths always starts with / like /home.

  • Relative paths starts without the /, and always append the passed url to the current url.

    • You can use ../, like in directories, to remove go back to upper Url paths.

    • You can use ./, to stay in the current path.

routerLinkActive

Used to attach a css class to elements, for instance, when selecting the select tabs.

Without exact: true, it will check as contained substrings. So / will always be true.

Programatically navigate router.navigate()

  • navigate() method doesn't know your currently route. (So relative paths don't add up)

    • If the Url passed is static, it can be the literal Url string.

    • For dynamic path, must use an Array of path segments.

      • These segments are added to the current Url.

      • Or to the one provided in relativeTo config property.

  • Some additional configs that you can pass to navigate() include:

    • replaceUrl: To avoid that the browser can go back to that route if you hit the back button.

    • relativeTo: Used for dynamic paths, the specified relativeTo will be the main Url where the paths will be added to.

    • queryParamsHandling: How navigate handles queryParams and fragments values after a navigation.

Passing queryParams

Passing fragments

Preserving queryParams and fragments - after Navigate with queryParamsHandling

  • merge: Will merge new params with existing queryParams.

  • preserve: Will just preserve the existent queryParams.

Nested Routes

Each child route will need a new <router-outlet> to render it's paths Components.

  • For instance, in the EmployeesComponent you will need to have a <router-outlet> which will be the place it's child routes will be loaded.

Now Each parent component will need to have a <router-outlet>, which is the place it will load it's children Components.

Nested routes to it's own file

You can grab the children routes and put them in a different .routes.ts file for more leaner structure.

Wildcard Routes

To handle routes that shouldn't exist.

  • ** is the wildcard and will catch everything that is not currently specified on the routes.

  • The order that you use it is VERY IMPORTANT, always use them as the last route.

To be able to redirect with urls that may always trigger like path: '', you can use the option pathMatch: 'full'

You can use more complex logic in redirect, returning a string or UrlTree.

pathMatch option

  • prefix: Will look at the route's path and combine with parent paths if available, and then checks if the Url in the browser STARTS with this path.

  • full: Will look at the route's path and combine with parent paths if available, and then checks if the FULL Url in the browser is equal to this path.

Setting the Page Title

Each page in your application should have a unique title so that they can be identified in the browser history.

The Router sets the document's title using the title property.

You can also provide custom title strategies:

  • By providing ResolverFn functions.

  • Or by extending the TitleStrategy, check the docs.

static titles

dynamic title

You can provide dynamic title values by using resolver functions, just like in dynamic data.

Passing static and dynamic Data to a Route

You can use both methods at the same time.

static data

You can pass static data to routes by providing them in the data property.

Access with Signals

You can then access the data inside the Component with input(), by having a variable with the same name as the data property.

Access with ActivatedRoute - with data (Observable)

data Observable will provide values from static and dynamic.

dynamic data - with ResolveFn functions

You can pass dynamic data to routes with resolve property of routes.

The resolve accepts an object just like the static one, but instead of static values you will provide valid Angular resolvers, which are functions.

The resolver will be called for every navigation action on the specific route.

  • BUT by default will NOT be re-executed when queryParams changes.

  • To allow re-execution set the runGuardsAndResolvers to always or paramsOrQueryParamsChange.

dynamic data - with Resolve Classes as Services (Avoid)

You can pass dynamic data to routes with services implementing Resolve class.

Fetching Url data - with input()

Changes in the URL will use still use the same Component's instance.

This means that ngOnInit will NOT execute again, and changes in :params for instance will not be picked.

Retrieving data with Signals will garantee to get the new values.

Access Parent Route Data

With input() the Component can always access it's own url data, BUT the Component cannot access by default it's parent route url data.

Provide an additional configuration withRouterConfig(), with paramsInheritanceStrategy property.

Just consider still using UNIQUE names to avoid clashing of param names in the routes.

Retrieving param /:userId

You can retrieve url parameters by having a variable with the exact same name as declared in the Route.

The expected type will always be string since the url is a string.

Retrieving multiple params /:userId/:name

Retriving Url queryParams ?allowEdit=value

Just like a /:param, for queryParams just create a variable with the same name as the queryParam.

Retrieving Url fragments #loading

Fetching Url data - with ActivatedRoute service

With Observables a Component can by default access it's own route params AND parent route params.

Changes in the URL will use still use the same Component's instance.

This means that ngOnInit will NOT execute again, and changes in :params for instance will not be picked.

Retrieving data with Observables will garantee to get the new values.

Retriving data with snapshot will NOT get new values.

Fetching data the Reactive way - with (Observable)

Retrieving Url params /:userId - with paramMap

You can access url params by subscribing to paramMap property of ActivatedRoute.

Retrieving Url multiple params /:userId/:name - with paramMap

Retrieving Url queryParams ?allowEdit=value - with queryParams

You can access url queryParams by subscribing to queryParams property of ActivatedRoute.

Retrieving Url fragments #loading - with fragment

You can access url fragment by subscribing to fragment property of ActivatedRoute.

Fetching data NOT Reactive - with (.snapshot)

Values from the snapshot are not Observables, they are actual values to be accessed.

The snapshot values are NOT reactive to the Url changes. (The values displayed will be the values of the FIRST run on the Component)

Retrieving Url param /:userId - with snapshot.paramMap or snapshot.params

Retrieving Url queryParams ?allowEdit=value - with snapshot.queryParamMap or snapshot.queryParams

Retrieving Url fragments #loading - with snapshot.frament

Only one fragment may be passed.

Route Guards

It is code that can be executed before a route is loaded or when leaving a route, that checks whether a certain navigation action should be permitted or not.

Typically guards will have their own files <guard-name>.guard.ts.

Useful for preventing unauthorized access.

Add Guards to routes by using the routes properties that start with can.

By default a Guard will guard the Route where it was declared, and it's child routes.

Guards can be defined by:

  • Guard functions.

  • Guard Services that implement certain interfaces (This is the old way)

canMatch

Allows you to control whether the entire route should be matched by a certain navigation action or not.

For instance, if some path that has been entered into the Url should match this route or not.

with Functions

with Classes

canActivate

Comes one step after canMatch but before the component has been loaded.

It will be checked by Angular once a route has been identified as matching for the currently active path.

canActivateChild

  • Can be used if you want to activate the route, the Component, but not necessarily the child components of that route.

canDeactivate

To control whether a user is allowed to leave a page or not.

Last updated