Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use the activated route's data DIRECTLY in the HTML template containing the RouterOutlet?

This one took me a while to figure out, so I hope to save someone's time by sharing the solution in the SO's Q&A way. Here it goes:

Goal

I have an Angular8 web application, where I use the RouterModule to navigate between the components.

Here is how my routes are defined:

const routes: Routes = [
    { path: 'moo', component: AppMooComponent, data: { title: 'Moo Section', desc: 'Moo is the first example component.' } },
    { path: 'boo', component: AppBooComponent, data: { title: 'Boo Section', desc: 'Boo is the second example component.' } },
    { path: 'foo', component: AppFooComponent, data: { title: 'Foo Section', desc: 'Foo is the third example component.' } },
    { path: '', redirectTo: 'moo', pathMatch: 'full' },
];

I would like to be able to use data.title and data.desc (or any defined data for that matter) in my HTML template in the following way:

<ul>
    <li><a [routerLink]="['moo']">Moo</a></li>
    <li><a [routerLink]="['boo']">Boo</a></li>
    <li><a [routerLink]="['foo']">Foo</a></li>
</ul>
<hr>
<h1>{{<something>.data.title}}</h1>
<p>{{<something>.data.desc}}</p>
<hr>
<router-outlet></router-outlet>

Problem

Injecting ActivatedRoute to get the data does not work, because ActivatedRoute is:

A service that is provided to each route component

and the component, containing the router-outlet is not a route component.

Research

I have searched the site and found the following questions discussing a very similar problem:

How can I access an activated child route's data from the parent route's component?

Get route data outside the router outlet

Access activated route data from some other component

Accessing Route data in root component, route data is empty

Angular ActivatedRoute data returns an empty object

However, in my case the emphasize is on direct usage of the route's data in the HTML template, so neither of those possible solutions is suitable (as summarized in How To Get Route Path Parameters In Non-Routed Angular Components):

  • Moving the non-routed component inside of the routed component
  • Using router navigation events
  • Creating an additional service to hold the route path param state and make it available for all other interested components

How to achieve that in the desired way?

like image 678
scopchanov Avatar asked Aug 11 '19 04:08

scopchanov


People also ask

How do you use a Routeroutlet?

The router-outlet is a directive that's available from the @angular/router package and is used by the router to mark where in a template, a matched component should be inserted. Thanks to the router outlet, your app will have multiple views/pages and the app template acts like a shell of your application.

How do I use the router outlet in Angular 13?

Router-outlet in Angular works as a placeholder which is used to load the different components dynamically based on the activated component or current route state. Navigation can be done using router-outlet directive and the activated component will take place inside the router-outlet to load its content.


1 Answers

Solution

I would suggest you to use a template variable reference as shown in the documentation:

#myTemplateVar="outlet"

Then you can access the route's data via the activatedRouteData: Data property of <router-outlet> and use it in the HTML template like this:

<h1>{{myTemplateVar.activatedRouteData.title}}</h1>
<p>{{myTemplateVar.activatedRouteData.desc}}</p>
<hr>
<router-outlet #myTemplateVar="outlet"></router-outlet>

Example

I have prepared a simple example for you on Stackblitz in order to demonstrate the proposed solution.

Result

Here how the result looks like (it is similar for the other routes/components):

Component Moo loaded and the route's data is displayed

like image 50
scopchanov Avatar answered Oct 11 '22 01:10

scopchanov