angularjsbreadcrumbs

Breadcrumb without child components/routes


I was trying to follow the answer in Angular breadcrumbs with dynamic label to implement a breadcrumb navigation for my angular app.

The difference to my app is that my components don't have the child relationships of the example:

Snippet of my routing module:

{
    path: '',
    component: NavbarComponent,
    canActivate: [authGuard],
    children: [
      {path: 'profile', component: ProfileComponent},
      {path: 'teams', component: TeamsComponent, data: {breadcrumb: 'Teams'}},
      {path: 'teams/:teamId/members', component: TeamMembersComponent, data: {breadcrumb: 'Members'}},
      {path: 'projects', component: ProjectsComponent},
      {path: 'projects/:id', component: ProjectDetailsComponent},

I have a few cases where I have a list overview, then I click on an entry, e.g. a specific project or team and get to a detail view which is rendered in its own component.

Implementing the breadcrumb as stated I don't get the nested structure but only "Members" instead of "Teams / Members".

In the end I want to use static breadcrumbs, defined in the route config, dynamic breadcrumbs with resolvers.

How can I solve this? Is there a way to have those hierarchical routes without actually rendering the component in the parent? Currently I don't use router outlets or something similar.

Since I am kind of a beginner with angular I am not sure if my page structure is suboptimal or if I need to adjust the breadcrumb logic.

Update:

I worked around a bit and for the projects this works:

  {path: 'projects', data: {breadcrumb: "Projects"}, children: [
          {path: '', data: {breadcrumb: null}, component: ProjectsComponent},
          {path: ':id', data: { breadcrumb: null}, resolve: { apiData: projectResolver}, component: ProjectDetailsComponent},
        ]},

However, with a bit more complex routes I still have a problem with the breadcrumb I can not understand yet:

 {path: 'admin/products', data: { breadcrumb: "Products" }, children: [
          {path: '', data: {breadcrumb: null}, component: ProductCategoriesOverviewComponent},
          {
            path: ':id', data: {breadcrumb: null}, resolve: { apiData: productResolver }, children: [
              {path: '', data: {breadcrumb: null}, component: ProductsEditComponent },
              {path: 'asset', data: {breadcrumb: "Asset"}, component: AssetFeatureComponent},
            ]
          },
        ]
      },

When navigating to admin/products the breadcrumb shows Products /. However, one level deeper: admin/products/755a5cee-2e5b-45d0-bd0d-05595be15705 I get Products / ResolvedName /ResolvedName /. ResolvedName is duplicate. Whats strange it that it works when I go one step further /admin/products/755a5cee-2e5b-45d0-bd0d-05595be15705/asset : Products /ResolvedName /Asset /

The resolver is simple:

export const productResolver: ResolveFn<Observable<any>> = (route: ActivatedRouteSnapshot) => {
  const productService = inject(ProductService);
  const productId = route.paramMap.get('id');
  return productService.getProduct(productId!).pipe(
    map((product) => ({
      breadcrumb: product.name
    })))
};

Solution

  • UPDATE:

    You should keep a routing path, for each section you want to display as a breadcrumb.

    {path: 'admin', data: { breadcrumb: "admin" }, children: [
     {path: 'products', data: { breadcrumb: "Products" }, children: [
              {path: '', data: {breadcrumb: null}, component: ProductCategoriesOverviewComponent},
              {
                path: ':id', data: {breadcrumb: null}, resolve: { apiData: productResolver }, children: [
                  {path: '', data: {breadcrumb: null}, component: ProductsEditComponent },
                  {path: 'asset', data: {breadcrumb: "Asset"}, component: AssetFeatureComponent},
                ]
              },
            ]
          },
       ],
    }
    

    You can try to keep a parent without a component and the child route will get rendered based on the path, you have to rework your routing to.

      {
        path: '',
        component: NavbarComponent,
        canActivate: [authGuard],
        children: [
          {path: 'profile', component: ProfileComponent},
          {
            path: 'teams', 
            data: {breadcrumb: 'Teams'}, 
            children: [
              { path: '', component: TeamsComponent },
              { path: '/:teamId/members', component: TeamMembersComponent, data: {breadcrumb: 'Members'} },
            ] 
          },
          {
            path: 'projects',
            children: [
              { path: '', component: ProjectsComponent },
              { path: '/:id', component: ProjectDetailsComponent },
            ] 
          },
          ...