Angular Route Ordering
The content of this post is based on Angular version >= 2.x unless explicitly stated otherwise.
In Angular, the ordering of the routes in the route configuration matters. And when using feature and routing modules, it is easy to get the routes out of their needed sequence.
Basic Configuration
The following is an example Angular route configuration commonly defined in an app.module.ts file:
RouterModule.forRoot([
{ path: ‘welcome’, component: WelcomeComponent } ,
{ path: ‘products’, component: ProductListComponent },
{ path: ‘product/:id’, component: ProductDetailComponent }
{ path: ”, redirectTo: ‘welcome’, pathMatch: ‘full’},
{ path: ‘**’, redirectTo: ‘welcome’, pathMatch: ‘full’ }
])
The welcome route displays the template for the Welcome Component. (www.mysite.com/welcome)
The products route displays the template for the Product List Component. (www.mysite.com/products)
The product/:id route is a parameterized route. It displays the template for the Product Detail Component with the product defined by the id parameter. (www.mysite.com/product/42)
The empty path specifies a default route. This is the route that is matched when no path is specified. In this example, the default route redirects to the welcome route. (www.mysite.com)
The ** defines a wildcard path. This is the route that is matched when no other prior route is matched. It is often used for displaying a 404 (not found) page. But in this example, it redirects to the welcome route. (www.mysite.com/hello)
These routes are processed from top to bottom and the first match wins.
If we moved the wildcard path up to the top of the list like this:
RouterModule.forRoot([
{ path: ‘**’, redirectTo: ‘welcome’, pathMatch: ‘full’ }
{ path: ‘welcome’, component: WelcomeComponent } ,
{ path: ‘products’, component: ProductListComponent },
{ path: ‘product/:id’, component: ProductDetailComponent }
{ path: ”, redirectTo: ‘welcome’, pathMatch: ‘full’}
])
None of the other routes would ever be matched. The wildcard would always be picked first. So take care on the ordering of the routes in your route configurations.
Feature Modules
As an application gets larger, it is best to break out the features into their own feature modules. This makes the code easier to work with and maintain.
In the above example, we can refactor the product features out of the app.module.ts and add them to their own product.module.ts (ProductModule):
RouterModule.forChild([
{ path: ‘products’, component: ProductListComponent },
{ path: ‘product/:id’, component: ProductDetailComponent },
])
The resulting app.module.ts routes then look like this:
RouterModule.forRoot([
{ path: ‘welcome’, component: WelcomeComponent },
{ path: ”, redirectTo: ‘welcome’, pathMatch: ‘full’ },
{ path: ‘**’, redirectTo: ‘welcome’, pathMatch: ‘full’ }
]),
ProductModule
But wait! Isn’t our wildcard route now ahead of our product routes? How will our product routes ever be matched?
As it turns out, Angular handles this differently than we may expect. When the RouterModule.forRoute or RouterModule.forChild is used directly, it is processed last. All of the Angular modules (such as ProductModule) are processed first. So even though we define the wildcard route above ProductModule in this example, the routes defined in the RouterModule.forRoot() are moved to the end and processed last. So all of our routes still work as expected.
Routing Modules
In some cases, we may want to remove the routes from the app.module.ts and move them to their own module, such as app-routing.module.ts (AppRoutingModule):
RouterModule.forRoot([
{ path: ‘welcome’, component: WelcomeComponent },
{ path: ”, redirectTo: ‘welcome’, pathMatch: ‘full’},
{ path: ‘**’, redirectTo: ‘welcome’, pathMatch: ‘full’ }
])
If we then simply replace the routes in app.module.ts with the routing module like this:
AppRoutingModule,
ProductModule
Our product routes will stop working. Now that all of our routes are in modules, they are processed in their defined order. So the wildcard path in the AppRoutingModule will come *before* any of the routes defined in the ProductModule.
The app.module.ts modules must instead be defined in the appropriate order:
ProductModule,
AppRoutingModule
For more information on routing, check out my Pluralsight course: “Angular 2: Getting Started”
For a code example, check out my github repo.
Enjoy!
Basyonic — January 14, 2017 @ 4:44 am
Excellent explanation, thanks!
deborahk — January 27, 2017 @ 4:59 pm
Thank you!
Rohit — February 12, 2017 @ 11:19 am
Hello Ms.Deborahk,
i am Rohit. i am following you in pluralsight.com. i like your teaching process and explain everything in-detail.
during practicing angular routing i have a issue ” module cannot loaded”. i am using webpack not systemjs.
I found it angular documentation “Angular provides a built-in module loader that supports SystemJS to load modules asynchronously. If you were using another bundling tool, such as Webpack, you would use the Webpack mechanism for asynchronously loading modules” .
It is a Lazy-Loading route configuration.
Can you resolve the issue.
Thank you
deborahk — February 20, 2017 @ 10:34 am
Your best bet is to post your question, with specifics, to StackOverflow. The experts there can help you.