Reputation: 138
app.routing.module.ts
const routes: Routes = [
{ path: '', component: AComponent },
...
{ path: 'homes/:id/:rate/:item', component: HomesComponent},
{ path: 'details/:id/:name/:product', component: DetailComponent},
...
]
As per client's requirement, we need to change the path to homes for both components. So we've updated the app.routing.module.ts.
Updated app.routing.module.ts
const routes: Routes = [
{ path: '', component: AComponent },
...
{ path: 'homes/:id/:rate/:item', component: HomesComponent},
{ path: 'homes/:id/:name/:product', component: DetailComponent},
...
]
but, due to the same number of parameters that we're using in each component we are getting conflict and it's not rendering properly, for all condition it is routing to HomesComponent that we've given first in the Routes list.
Do you guys have any suggestions to resolve this issue, without compromising the path and number of parameters?
Upvotes: 2
Views: 5146
Reputation: 91
When for scenario like above, depends upon query parameter and not as route param, i find @ritaj's answer useful with few more lines of code to check for the routes like below. As UrlMatcher does not seem to have access to activated route and thus the params with it.
Route
{ path: 'apply', component: ApplicationRouterComponent },
Route handler component
export class ApplicationRouterComponent implements OnInit {
type: string;
state: string;
constructor(private route: ActivatedRoute) { }
ngOnInit() {
this.route.queryParams.subscribe(q => {
this.type = q['type'];
this.state = q['state'];
});
}
showApplicationForm(): boolean {
return this.type !== 'new' || this.state !== 'inprogress';
}
showInProgressForm(): boolean {
return this.type === 'new' && this.state === 'inprogress';
}
}
Route handler html
<app-application *ngIf="showApplicationForm()"></app-application>
<app-resume *ngIf="showInProgressForm()"></app-resume>
Upvotes: 1
Reputation: 681
Use custom UrlMatcher
when paths
and parameters
are not helpful
Form official doc: A custom URL matcher can be provided when a combination of path and pathMatch isn't expressive enough
In your case i would create a custom matcher.
SOLUTION 1:
export const routes = [{
matcher: homeCustomerMatcher,
component: HomeComponent
}, {
matcher: detailsCustomerMatcher,
component: DetailsComponent
}];
Scenario A: If the data types are different for parameters. Assuming/:rate
params is number data type and /:name
is string
export function homeCustomerMatcher(url: UrlSegment[]){
return url.length === 3 && isInteger(url[1].path * 1) ? ({consumed: url}) : null;
}
Scenario B: If the /:name
values are pre defined. Assuming:/rate and :/name
is same date type
In this case we can create a collection/array of possible name values and compare the values again the path values.
const possibleNameValues = ["A","B","C"];
export function homeCustomerMatcher(url: UrlSegment[]){
return url.length === 3 && possibleNameValues.includes(url[1].path)
? ({consumed: url}) : null;
}
SOLUTION 2:
Using regex
with UrlMatcher
to match the param data type
{
path: 'homes/:id',
children: [
{
path: ':rate',
matcher: NumericUrlMatcher,
component: Ratecomponent
},
{
path: ':name',
component: NameComponent
}
}
Now you customer matcher function should be updated to
export function NumericUrlMatcher(url: UrlSegment[]) {
const regex = new RegExp(...);
const match = url[0].path.match(regex);
return match !== null && match[0].length === url[0].path.length;
}
Upvotes: 10
Reputation: 10127
You could make a wrapper component with the path
and programatically route
to different components.
const routes: Routes = [
{ path: '', component: AComponent },
...
{ path: 'homes/:id/:rate/:item', component: WrapperComponent},
...
]
Wrapper template:
<detail-component *ngIf="yourCondition"><detail-component>
<home-component *ngIf="!yourCondition"></home-component>
How would you go about finding the first method for yourCondition
I don't know.
However, I would definitely advise against this.
Upvotes: 4