Reputation: 1925
How do I set up my routes so that my parameter can take forward slashes?
For example: myapp.com/file/rootfolder/subfolder/myfile
This doesn't work:
const SECTION_ROUTES: Routes = [
{ path: 'file/:path', component: FileStoreComponent }
];
Is having / in routing parameter values possible?
I've read about URL approaches that use URL encoding. However, I'd like my user to be able to type the URL.
Upvotes: 9
Views: 12675
Reputation: 6893
This can be achieved by using a UrlMatcher.
To keep the matcher as simple as possible, we can use a parent route for the file
segment of the route, and then use a childRoute that handles the remaining path
.
const SECTION_ROUTES: Routes = [
{
path: "file",
children: [{
matcher: (segments: UrlSegment[]) => ({
consumed: segments,
posParams: {
path: new UrlSegment(segments
.map((segment) => decodeURIComponent(segment.path))
.join("/"),
{}
),
},
}),
component: FileStoreComponent
}],
},
];
Upvotes: 0
Reputation: 2290
try this for matching on path :path
const SECTION_ROUTES: Routes = [
{
matcher: t => t.length ? { consumed: t, posParams: { path: new UrlSegment(t.join('/'), {}) } } : null,
component: FileStoreComponent
}
];
Upvotes: 0
Reputation: 171
To achieve this with a recent version of Angular (9.X for me), you can use the Route.matcher
parameter. Here is an example:
function filepathMatcher(segments: UrlSegment[],
group: UrlSegmentGroup,
route: Route) : UrlMatchResult {
// match urls like "/files/:filepath" where filepath can contain '/'
if (segments.length > 0) {
// if first segment is 'files', then concat all the next segments into a single one
// and return it as a parameter named 'filepath'
if (segments[0].path == "files") {
return {
consumed: segments,
posParams: {
filepath: new UrlSegment(segments.slice(1).join("/"), {})
}
};
}
}
return null;
}
const routes: Routes = [
{ path: 'login', component: LoginComponent },
{ matcher: filepathMatcher, component: FilesComponent },
// ...
];
@NgModule({
imports: [RouterModule.forRoot(routes, { useHash: true })],
exports: [RouterModule]
})
export class AppRoutingModule { }
You will be able to access the parameter in your Component through the ActivatedRoute.paramMap
Note the query parameters are also working and preserved.
However, you will still have issues if the URL contains parenthesis, for example /files/hello(world:12)/test
because they are interpreted by angular as auxiliary routes
In this case, you can add a custom UrlSerializer to encode parenthesis and you'll have to decode them in your Component.
Upvotes: 7
Reputation: 2232
It looks like you have to escape each forward slash with a wildcard like so:
/*page
This question covers it: Angular2 RouterLink breaks routes by replacing slash with %2F
That question links to the following GitHub issue ticket that goes more in-depth: https://github.com/angular/angular/issues/8049
Upvotes: 1