Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular routing with segment wildcard

Tags:

angular

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?

like image 501
superstator Avatar asked May 04 '26 00:05

superstator


1 Answers

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('/');
}
like image 151
superstator Avatar answered May 11 '26 16:05

superstator