I've created a github repository which has a perfect example of my issue.
https://github.com/rjriel/dynamic-route-example
The important part of the code in this repo is in app.module.ts
let mainRoutes: Routes = [{
path: "first",
component: FirstComponent
}]
mainRoutes.push({
path: "second",
component: SecondComponent
})
@NgModule({
...
imports: [
RouterModule.forRoot(mainRoutes),
When running this code in development (ie. ng serve
) both routes navigate correctly. However, when running this code in production (ie. ng serve --prod
) the second
route that was added through mainRoutes.push
results in the following error:
ERROR Error: Uncaught (in promise): Error: Cannot match any routes. URL
Segment: 'second'
Error: Cannot match any routes. URL Segment: 'second'
at t.BkNc.t.noMatchError (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.selector (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.error (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.T14+.e._error (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.T14+.e.error (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.T14+.e._error (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.T14+.e.error (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.T14+.e._error (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.T14+.e.error (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.T14+.e._error (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at t.BkNc.t.noMatchError (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.selector (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.error (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.T14+.e._error (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.T14+.e.error (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.T14+.e._error (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.T14+.e.error (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.T14+.e._error (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.T14+.e.error (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.T14+.e._error (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at u (polyfills.8c1e4b56978ce6347832.bundle.js:1)
at u (polyfills.8c1e4b56978ce6347832.bundle.js:1)
at polyfills.8c1e4b56978ce6347832.bundle.js:1
at e.invokeTask (polyfills.8c1e4b56978ce6347832.bundle.js:1)
at Object.onInvokeTask (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.invokeTask (polyfills.8c1e4b56978ce6347832.bundle.js:1)
at r.runTask (polyfills.8c1e4b56978ce6347832.bundle.js:1)
at o (polyfills.8c1e4b56978ce6347832.bundle.js:1)
at t.invokeTask [as invoke] (polyfills.8c1e4b56978ce6347832.bundle.js:1)
at h (polyfills.8c1e4b56978ce6347832.bundle.js:1)
Would anybody happen to know why compiling for production would produce this error while it works completely fine in development? Or at least a better way to debug?
Edit:
The real life implementation of what I'm doing here is that I have multiple pages on a site with the same layout of information, so I created a json file that is an object where each key is the route and value is the information for the route. Then I load the json and add the routes, as shown here:
import * as PageLayouts from '../page-layouts.json'
import { MainLayoutComponent } from './main-layout/main-layout.component'
Object.keys(PageLayouts).forEach(key => {
mainRoutes.push({
path: key,
component: MainLayoutComponent
})
})
I do a console.log(mainRoutes)
after the above forEach and see all the routes in the array as expected. Also for clarification, this forEach
loop is done before the @NgModule
declaration, as shown in the example code. This all works totally fine with JiT compilation for development, but has the issues addressed above with AoT compilation for production.
Add the AppRoutingModule link. In Angular, the best practice is to load and configure the router in a separate, top-level module. The router is dedicated to routing and imported by the root AppModule . By convention, the module class name is AppRoutingModule and it belongs in the app-routing.
First, add links to the two components. Assign the anchor tag that you want to add the route to the routerLink attribute. Set the value of the attribute to the component to show when a user clicks on each link. Next, update your component template to include <router-outlet> .
A routed Angular application has one singleton instance of the Router service. When the browser's URL changes, that router looks for a corresponding Route from which it can determine the component to display.
Show activity on this post. You can check the current route by injecting the Location object into your controller and checking the path() , like so: class MyController { constructor(private location:Location) {} ...
The short answer is that when you compile for production, it uses the Ahead of Time (AOT) process instead of the Just in Time (JiT) process. That is why you are seeing different results.
You can read more about AOT here: https://angular.io/guide/aot-compiler
And this article may be helpful: http://blog.mgechev.com/2016/08/14/ahead-of-time-compilation-angular-offline-precompilation/
Just guessing here ... but is it possible that this code is not actually executing when it is compiled with the AOT compiler?
mainRoutes.push({
path: "second",
component: SecondComponent
})
It does not appear to be within any Angular component or service.
Could you be more explicit about what you are trying to accomplish with this code? Are you trying to load dynamic components?
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