0

In Angular 8, for

const routes: Routes = [
  { path: 'page', component: MyPageComponent, data: {title: "Page"} }
];

how can I bind route.data.title in HTML?

<a routerLink="/page">{{???.data.title}}</a>
Anton
  • 455
  • 6
  • 12

1 Answers1

0

Instead of trying to query the routes themselves (which is done easily after a routing event), I would store page names in one place:

export const appTitles = {
  myPage: 'Page'
};

const routes: Routes = [
  { path: 'page', component: MyPageComponent, data: {title: appTitles.myPage} }
];

Component HTML:

<a routerLink="/page">{{title}}</a>

Component ts:

title = appTitles.myPage;

EDIT:

I store my routes in their own object:

export const appRoutes: Routes = [
    {
      path: '/home', component: HomeComponent, data: { title: 'Home' }
    }
];

I could probably achieve what you want to by creating a service that queries and caches the data.title by url, e.g.:

export class RouteTitleService {

  private cache = {};

  getTitle(path: string): string {
    if (this.cache.hasOwnProperty(path)) {
      return this.cache[path];
    }

    for (let i = 0; i < appRoutes.length; i++) {
      // TODO: common function for querying an array of routes
      string title = this.getTitleFromRoute(appRoutes[i], path);
      if (typeof(title) === 'string') {
        this.cache[path] = title;
        return title;
      }
    }

    return null;
  }

  private getTitleFromRoute(route: Route, path: string): string {
    if (route.path === path) {
      return route.data ? route.data.title : '';
    }

    if (route.children) {
      if (let i = 0; i < route.children.length; i++) {
        string title = this.getTitleFromRoute(route.children[i], path);
        if (typeof(title) === 'string') {
          return title;
        }
      }
    }

    return null;
  }
}

NB, this is not tested, and may not be relevant to your case, but it's something I may think about doing properly.

My app routing module is then simple:

@NgModule({
  imports: [RouterModule.forRoot(appRoutes, {
    preloadingStrategy: PreloadAllModules
  })],
  exports: [RouterModule],
  providers: [
    { provide: UrlSerializer, useClass: LowerCaseUrlSerializer },
  ]
})
export class AppRoutingModule {}
Kurt Hamilton
  • 12,490
  • 1
  • 24
  • 40
  • What I'm trying to achieve is to reduce copy-paste of `data: {title: "**Page**"}` to `**Page**`. In your code instead `path: '**page**'...` is copied to `appTitles.my**Page**`, trading copy-paste for copy-paste. Imagine an app having 50+ routes, its a very error-prone approach – Anton Feb 06 '20 at 15:58
  • I get your point. I must say, I've often thought about looking into this, but I've never needed to get route titles up front, only after navigation, which becomes fairly trivial. – Kurt Hamilton Feb 06 '20 at 16:00
  • I store my routes in their own object, and could theoretically traverse the hierarchy to find the title, matching by url. I could then cache the titles by url to avoid multiple recursions. Does that make sense? – Kurt Hamilton Feb 06 '20 at 16:02