Reputation: 353
I have an issue with angular routing.
When I try to go to the my.domain/new-york
I've got correct page (HomeComponent
)
But when I try to go to the my.domain/new-york/search
I've got HomeComponent
to instead SearchComponent
. What I did wrong?
const routes: Routes = [
{
path: '',
component: BasicComponent,
children: [
{
path: '',
component: HomeComponent,
data: {
headerDark: true
}
},
{
path: ':city',
component: HomeComponent,
data: {
headerDark: true
},
children: [
{
path: ':category',
component: HomeComponent
},
{
path: 'search',
component: SearchComponent,
data: {
headerDark: true
}
},
]
},
]
}
];
UPD: I use two modules:
const routes: Routes = [
{
path: '',
loadChildren: () => import('./modules/basic/basic.module').then(mod => mod.BasicModule),
runGuardsAndResolvers: 'always'
},
{
path: 'dashboard',
canActivate: [AuthService],
loadChildren: () => import('./modules/dashboard/dashboard.module').then(mod => mod.DashboardModule)
},
{
path: '**',
redirectTo: '/'
}
];
UPD 2: Example https://stackblitz.com/edit/angular-ghafx6?file=src%2Fapp%2Forders%2Forders-routing.module.ts
Upvotes: 3
Views: 2187
Reputation: 11
The answer of @KShewengger didn't work for me because I didn't want the ChildComponents (SearchComponent) to be rendered inside the ParentComponent (HomeComponent). In my case I was only using the routing config to construct a breadcrumb. My ChildComponents however should always be rendered in my global <router-outlet>
in my AppComponent
completely replacing the ParentComponent in the DOM
My solution ended up like this:
{
path: ':city',
children: [
{
path: '',
component: HomeComponent,
},
{
path: 'search',
component: SearchComponent,
}
{
path: ':category',
component: HomeComponent
}
]
},
A bit of explanation (although I'm no 100% sure about that): If you have childroutes, you always need a <router-outlet>
in the ParentComponent. Else the child routes are pretty much ignored.
Changing the path: ':city'
to be a componentless route was crucial here, so that my SearchComponent got rendered in the end.
I'm still quite the Angular noob and can't explain all the internals, but I hope this might help someone in the future.
Upvotes: 0
Reputation: 2864
Order of routes are very important if you are using dynamic routes.
Here issue is issue is search
after city name is consider as category
because category
is a dynamic route
and it comes before static route
. So it is always recommended that dynamic route
must comes at the end.
For your problem change you routes this way will solve your problem.
const routes: Routes = [
{
path: '',
component: BasicComponent,
children: [
{
path: '',
component: HomeComponent,
data: {
headerDark: true
}
},
{
path: ':city',
component: HomeComponent,
data: {
headerDark: true
},
children: [
{
path: 'search',
component: SearchComponent,
data: {
headerDark: true
}
},
{
path: ':category',
component: HomeComponent
},
]
},
]
}
];
See the Stackblitz for reference
EDITED
As per your stackblitz below 2 changes required.
city.component.html
added <router-outlet></router-outlet>
orders.component.html
<a [routerLink]="['/new-york']">
City
</a>
<a [routerLink]="['/new-york/shops']">
Category
</a>
<a [routerLink]="['/new-york/search']">
Search
</a>
<router-outlet></router-outlet>
See the Stackblitz for reference
Upvotes: 3
Reputation: 8269
This is because in your code, you have initialized the /:category
first before the search
so the search
keyword was being read as a category parameter.
Try to reorder the routes to:
children: [
{
path: 'search',
component: SearchComponent,
data: {
headerDark: true
}
},
{
path: ':category',
component: HomeComponent
},
]
UPDATE:
You can also try multiple parameter instances using this method. Take note of the order.
Method #1:
Attached StackBlitz Demo for your reference. You can check it's console as well
children: [
{
path: ':city/search',
component: SearchComponent
},
{
path: ':city/:category',
component: HomeComponent,
},
{
path: ':city',
component: HomeComponent
}
]
Method #2:
Based on your routes above and upon testing what you wanted to do on those routes under the :city
is that you wanted to render those components under the CityComponent or in your case at HomeComponent but no children is being rendered?
This is because you need to add a <router-outlet>
inside your HomeComponent to render your children components.
{
path: ':city', // This is your parent route and parent component which you expect those child components below will be rendered in here. Thus, you need to specify a router-outlet in here.
component: HomeComponent,
...
children: [ // This is your child components that will render/reflect it's templates to their parent above or in this case, inside the HomeComponent
{
path: ':category',
component: HomeComponent // This will render the category -> home template/component inside the parent's HomeComponent
},
{
path: 'search',
component: SearchComponent, // this will render the search template/component inside the parent's HomeComponent
}
]
},
If you want to have it in distinct routes, the Method #1 solution above would help you with it.
Upvotes: 3