3

Is there a way to inject and use a service in the route list in the Angular routing module in order to dynamically change route data?

Like so:

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { MyComponent } from './my/my.component';

const routes: Routes = [
  { path: 'about', component: AboutComponent, data: {title: myService.getTitle()}} // use it?
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule {
    constructor(private myService: SomeService) {} // inject it
}

How could I achieve dynamic behavior, like setting a custom title, in routes array?

dzenesiz
  • 1,388
  • 4
  • 27
  • 58

2 Answers2

3

You probably want to take a look at Resolve

@Injectable({ providedIn: 'root' })
export class TitleResolver implements Resolve<Hero> {
  constructor(private service: TitleService) {}

  resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<any>|Promise<any>|any {
    return this.service.getTitle();
  }
}

in router

const routes: Routes = [
  { 
     path: 'about', 
     component: AboutComponent, 
     resolve: { // use `resolve`
       title: TitleResolver
     } 
];
deerawan
  • 8,002
  • 5
  • 42
  • 51
  • Great! Could you maybe also tell me if I can access `route.data.someCustomProperty` and use it in resolve? Currently, it is not present when `resolve()` triggers. I've looked online, but no luck. – dzenesiz Dec 04 '20 at 10:23
  • 1
    @dzenesiz hmm, seems that's not possible. How about storing that custom property in the service, then inject it into TitleResolver? – deerawan Dec 04 '20 at 19:10
  • I actually managed to pass data like this `data: { myData: 'whatever}` and then use it in resolver by accessing `route.data.myData`. I have just one more question, if that's okay - do I need to set the resolved value manually in component, or will title get set automatically? I'm asking because it seems it won't be automatic. – dzenesiz Dec 08 '20 at 10:28
0

you can access title in your routes

const routes = [
  { path: 'about', customData: myValue, component: AboutComponent, data: {title: myService.getTitle()}} // use it?
];

in any components or services with:

@Injectable({
  providedIn: 'root'
})
export class MyService {
  constructor(private router: Router) { };
  ...
  this.router.config[0].data.title;
  ...
}
tbo47
  • 2,688
  • 3
  • 20
  • 11