Search code examples
angularroutesangular-routing

Get dynamic route parameter value in app-component and add it to every route of the app in Angular 12


In my Angular 12 app, I have a requirement to extract value of a route parameter when the app loads and add it to every route in the app. The user of the app will be sent a URL like https://testdomain.blah/car/welcome. Now the value 'car' in the route is dynamic. It can be 'bus', 'bike'. etc. I have to pick up that value in the app-component and add it to each route in the app. So when the user navigates to another route like details for example, the URL should be https://testdomain.blah/car/details/uid

The routes defined in app-routing.module.ts file are

const routes: Routes = [
 {
    path: ':type',
    children: [
        {
            path: '',
            redirectTo: 'welcome',
            pathMatch: 'full'
        },
        {
            path: 'welcome',
            loadChildren: () => import('./welcome/welcome.module').then(m => m.WelcomeModule)
        },
        {
            path: 'details/:uid',
            loadChildren: () => import('./details/details.module').then(m => m.DetailsModule)
        },
        {
            path: '**',
            redirectTo: 'welcome',
            pathMatch: 'full'
        }
    ]
 }
];

I am trying to fetch the dynamic route parameter value in app.component.ts file as shown below

this.activatedRoute.paramMap.subscribe((params: ParamMap) => {
        console.log(params.get("type"));
    });

But null value is logged in console. So I am not able to get that 'car' value in the app component. I couldn't figure out what is causing this issue and how to add this parameter to every route in the app. Please help me out with this.


Solution

  • Since you are dependent on AppComponent which is the root component also, for your use case, you will need to have a separate root component, which will display AppComponent and then AppComponent can listen to params:

    create a wrapper root component:

    import { Component } from '@angular/core';
    
    @Component({
      selector: 'root',
      template: `<router-outlet></router-outlet>`,
    })
    export class RootComponent {
      constructor() {  }
    }
    

    modify your index.html to remove your app component selector and use this:

    <root>Loading...</root>
    

    Then modify the routing to include AppComponent:

    const routes: Routes = [
     {
        path: ':type',
        component: AppComponent
        children: [
            {
                path: '',
                redirectTo: 'welcome',
                pathMatch: 'full'
            },
            {
                path: 'welcome',
                loadChildren: () => import('./welcome/welcome.module').then(m => m.WelcomeModule)
            },
            {
                path: 'details/:uid',
                loadChildren: () => import('./details/details.module').then(m => m.DetailsModule)
            },
            {
                path: '**',
                redirectTo: 'welcome',
                pathMatch: 'full'
            }
        ]
     }
    

    Modify your app module to bootstrap Root component:

     declarations: [AppComponent, RootComponent],
     bootstrap: [RootComponent]
    

    Now your activate route subscription should work.