superstator
superstator

Reputation: 3208

Angular routing with segment wildcard

I am setting up routing for an Angular 6 app, and I want to have a route which can match a variable number of segments. Currently I have a route config that looks like this:

const routes: Routes = [
  { path: '', redirectTo: '/catalog', pathMatch: 'full' },
  { path: 'login', component: LoginFormComponent },
  { path: 'catalog', component: CatalogComponent, canActivate: [SessionGuard] },
  { path: 'repo/:name', component: RepositoryComponent, canActivate: [SessionGuard] }
];

That matches a url like repo/test and sends it to the RepositoryComponent, but repo/foo/bar raises an error:

ERROR Error: Uncaught (in promise): Error: Cannot match any routes. URL Segment: 'repo/foo/bar'
Error: Cannot match any routes. URL Segment: 'repo/foo/bar'
    at ApplyRedirects.push../node_modules/@angular/router/fesm5/router.js.ApplyRedirects.noMatchError (router.js:1341)

I am used to the convention in ASP.NET MVC which allows me to declare a route like this:

[HttpGet("repo/{*name}")]

Which would match both repo/test and repo/foo/bar and place everything after the first slash (test or foo/bar) in a name argument. Is there a way to get equivalent behavior with Angular?

Upvotes: 3

Views: 1151

Answers (1)

superstator
superstator

Reputation: 3208

Apparently there is no built-in way to do this. What I've ended up with is a routing setup like this:

const routes: Routes = [
  { path: '', redirectTo: '/catalog', pathMatch: 'full' },
  { path: 'login', component: LoginFormComponent },
  { path: 'catalog', component: CatalogComponent, canActivate: [SessionGuard] },
  { path: 'repo', component: RepositoryComponent, canActivate: [SessionGuard], children: [{
    path: '**', component: RepositoryComponent
  }] }
];

That handles the request routing, but not the parameter evaluation. To get the segments matched by the ** wildcard, I need to scrounge around in the injected Router object on my RepositoryComponent:

getRepo(): void {
  this.Name = this.route.snapshot.children[0].url.join('/');
}

Upvotes: 3

Related Questions