You can define multiple routes with and without parameter:
@RouteConfig([
{ path: '/user/:id', component: User, name: 'User' },
{ path: '/user', component: User, name: 'Usernew' }
])
and handle the optional parameter in your component:
constructor(params: RouteParams) {
var paramId = params.get("id");
if (paramId) {
...
}
}
See also the related github issue: https://github.com/angular/angular/issues/3525
{path: 'users', redirectTo: 'users/', pathMatch: 'full'},
{path: 'users/:userId', component: UserComponent}
This way the component isn't re-rendered when the parameter is added.
It's recommended to use a query parameter when the information is optional.
Route Parameters or Query Parameters?
There is no hard-and-fast rule. In general,
prefer a route parameter when
- the value is required.
- the value is necessary to distinguish one route path from another.
prefer a query parameter when
- the value is optional.
- the value is complex and/or multi-variate.
from https://angular.io/guide/router#optional-route-parameters
You just need to take out the parameter from the route path.
@RouteConfig([
{
path: '/user/',
component: User,
as: 'User'
}])
Angular 4 - Solution to address the ordering of the optional parameter:
DO THIS:
const appRoutes: Routes = [
{path: '', component: HomeComponent},
{path: 'products', component: ProductsComponent},
{path: 'products/:id', component: ProductsComponent}
]
Note that the products
and products/:id
routes are named exactly the same. Angular 4 will correctly follow products
for routes with no parameter, and if a parameter it will follow products/:id
.
However, the path for the non-parameter route products
must not have a trailing slash, otherwise angular will incorrectly treat it as a parameter-path. So in my case, I had the trailing slash for products and it wasn't working.
DON'T DO THIS:
...
{path: 'products/', component: ProductsComponent},
{path: 'products/:id', component: ProductsComponent},
...
rerezz's answer is pretty nice but it has one serious flaw. It causes User
component to re-run the ngOnInit
method.
It might be problematic when you do some heavy stuff there and don't want it to be re-run when you switch from the non-parametric route to the parametric one. Though those two routes are meant to imitate an optional url parameter, not become 2 separate routes.
Here's what I suggest to solve the problem:
const routes = [
{
path: '/user',
component: User,
children: [
{ path: ':id', component: UserWithParam, name: 'Usernew' }
]
}
];
Then you can move the logic responsible for handling the param to the UserWithParam
component and leave the base logic in the User
component. Whatever you do in User::ngOnInit
won't be run again when you navigate from /user to /user/123.
Don't forget to put the <router-outlet></router-outlet>
in the User
's template.
The suggested answers here, including the accepted answer from rerezz which suggest adding multiple route entries work fine.
However the component will be recreated when changing between the route entries, i.e. between the route entry with the parameter and the entry without the parameter.
If you want to avoid this, you can create your own route matcher which will match both routes:
export function userPageMatcher(segments: UrlSegment[]): UrlMatchResult {
if (segments.length > 0 && segments[0].path === 'user') {
if (segments.length === 1) {
return {
consumed: segments,
posParams: {},
};
}
if (segments.length === 2) {
return {
consumed: segments,
posParams: { id: segments[1] },
};
}
return <UrlMatchResult>(null as any);
}
return <UrlMatchResult>(null as any);
}
Then use the matcher in your route config:
const routes: Routes = [
{
matcher: userPageMatcher,
component: User,
}
];
With angular4 we just need to organise routes together in hierarchy
const appRoutes: Routes = [
{
path: '',
component: MainPageComponent
},
{
path: 'car/details',
component: CarDetailsComponent
},
{
path: 'car/details/platforms-products',
component: CarProductsComponent
},
{
path: 'car/details/:id',
component: CadDetailsComponent
},
{
path: 'car/details/:id/platforms-products',
component: CarProductsComponent
}
];
This works for me . This way router know what is the next route based on option id parameters.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With