Is there a way to send static routing data with a parameterized path?

56 Views Asked by At

I'm passing static route data in my route definition like this:

const routes: Routes = [{ path: '/map',
                          component: MapComponent,
                          data: { animation: 'mapPage' } }];

Then access it in my component via:

constructor(private _contexts: ChildrenOutletContexts) { }

getRouteAnimationData(): Data | unknown {
  return this._contexts.getContext('primary')?.route?.snapshot?.data?.['animation'];
}

However, I now also have a parameterized route:

const routes: Routes = [{ path: '/record/:type',
                          component: RecordComponent,
                          data: { animation: ':typePage' }

Now, of course this will only send the static string ':typePage' and not, 'areaPage' or 'languagePage', depending on the actual value of :type.

Is there a way to get this parameter added to the data value?

2

There are 2 best solutions below

1
Rainy sidewalks On

i am very unsure that if i gets you correctly ,so pleae elaborate and explain the exact your need in more better .

mean while what you need is use of ParamMap

getRouteAnimationData(): string {
    const type = this.route.snapshot.paramMap.get('type');
    return type + 'Page';
  }

please let me know more on you requirement if i got you wrong

8
Naren Murali On

The data is meant for static properties only, instead you can go for state which is more dynamic, please find below working example demonstrating the usage of state!

child

import { Component, OnInit } from '@angular/core';
import {
  ActivatedRoute,
  Data,
  NavigationEnd,
  Router,
  Params,
} from '@angular/router';
import { filter } from 'rxjs';

@Component({
  selector: 'app-child',
  template: `<p>
  from state animation! - {{animation}}
  from params! - {{paramValue}}
  </p>`,
  standalone: true,
})
export class ChildComponent implements OnInit {
  animation: string = '';
  paramValue: string = '';
  constructor(private activatedRoute: ActivatedRoute, private router: Router) {}

  ngOnInit() {
    // this.router.events
    //   .pipe(filter((e) => e instanceof NavigationEnd))
    //   .subscribe((e) => {
    //     const navigation = this.router.getCurrentNavigation();
    //     this.animation =
    //       navigation?.extras?.state?.['animation'] ||
    //       this.activatedRoute.snapshot?.data?.['animation'];
    //   });
    // or

    this.activatedRoute.params.subscribe((params: Params) => {
      this.paramValue = params['type'];
      const navigation = this.router.getCurrentNavigation();
      this.animation =
        navigation?.extras?.state?.['animation'] ||
        this.activatedRoute.snapshot?.data?.['animation'];
    });
  }
}

parent

import { Component } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { RouterModule, provideRouter } from '@angular/router';
import 'zone.js';
import { ChildComponent } from './child/child.component';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterModule, ChildComponent],
  template: `
    <a routerLink="/record/helloType" [state]="{animation: 'fromHTML'}">
      navigate to child from html with data 'fromHTML'
    </a> | 
    <a routerLink="/record/asdfType" [state]="{animation: 'fromHTML2'}">
      navigate to child from html with data 'fromHTML2'
    </a>
    <router-outlet/>
  `,
})
export class App {
  name = 'Angular';
}

bootstrapApplication(App, {
  providers: [
    provideRouter([
      {
        path: 'record/:type',
        component: ChildComponent,
        data: { animation: 'mapPage' },
      },
    ]),
  ],
});

stackblitz demo