Search code examples
angularangular-ui-router

better way to declare multiple depth routes in angular


I have two main routes I would like to make. One which is assets/ANY_NUMBER_OF_LEVELS/browse and assets/ANY_NUMBER_OF_LEVELS. The components that receive the ANY_NUMBER_OF_LEVELS ideally would just receive an array of the levels.

Currently I am doing it like this:

const routes: Routes = [
  { path: '', component: BrowseComponent },

  // all possible paths for browse //
  { path: 'assets/:level1/:level2/:level3/:level4/browse', component: BrowseComponent },
  { path: 'assets/:level1/:level2/:level3/browse', component: BrowseComponent },
  { path: 'assets/:level1/:level2/browse', component: BrowseComponent },
  { path: 'assets/:level1/browse', component: BrowseComponent },
  { path: 'assets/browse', component: BrowseComponent },

  // all possible paths for assets //
  { path: 'assets/:level1/:level2/:level3/:level4/:id', component: AssetComponent },
  { path: 'assets/:level1/:level2/:level3/:id', component: AssetComponent },
  { path: 'assets/:level1/:level2/:id', component: AssetComponent },
  { path: 'assets/:level1/:id', component: AssetComponent },
  { path: 'assets/:id', component: AssetComponent },
  { path: '**', component: NotFoundComponent }
];

Which, while it certainly does work, isn't very elegant. Is there a better way of doing this?


Solution

  • I think you can use UrlMatcher for this.

    Here's a way to implement it:

    const assetsUrlMatcher = (segments: UrlSegment[], group: UrlSegmentGroup, route: Route) => {
    
      if (!segments.length || segments[0].path !== 'assets') {
        return null;
      }
    
      return { 
        consumed: segments,
        posParams: {
          id: segments[segments.length - 1],
          // Add other segments here..
        }
      };
    };
    
    const routes: Routes = [
      /* ... */
      {
        path: assetsUrlMatcher,
        component: AssetComponent,
      }
      /* ... */
    ];
    
    <button [routerLink]="['assets/level1/level2/level3/', 123]">Multiple levels</button>
    

    StackBlitz.