angularangular-routingdynamic-routing

Angular dynamic component loading through a config file


I have a question about angular dynamic component loading through an environment config file.

Below is a sample of my environment file:

routes: [
  {
    name: 'auth/logout',
    path: '../../components/logout/logout.component',
    class: 'LogoutComponent',
  },
  {
    name: 'base/home',
    path: '../../components/home/home.component',
    class: 'LogoutComponent',
  }
]

and in my app.component.ts:

...
@ViewChild('dynamicComponentContainerPage', { read: ViewContainerRef, static: true }) container!: ViewContainerRef;

constructor(private injector: Injector) { }

ngOnInit(): void {
    this.loadThemeComponent(routeFromBackend);
}

async loadDynamicComponent(route: { name: string, path: string, class: string }) {
    this.container.createComponent(import(route.path).then(m => m[route.class]), { injector: this.injector });
}
...

The error I am getting is: ERROR TypeError: Failed to fetch dynamically imported module: http://localhost:4200/page404/page404.component?import

Thank you for your time, Damian


Solution

  • in all modern build tools static analysis for paths is almost essential. i.e. you can't import(randomString) (you can, but it is a hard and restrictive way and you probably shouldn't). but you can make a function with import and leverage it afterwards

    routes: [
      {
        name: 'auth/logout',
        // this way bundler will handle the import correctly
        loadComponent: () => import('../../components/logout/logout.component').then(m => m.LogoutComponent),
      },
    ....
    ]
    
    async loadDynamicComponent(route: { name: string, loadComponent: () => Promise<Type<unknown>> }) {
        this.container.createComponent(await route.loadComponent(), { injector: this.injector });
    }