Search code examples
angularlazy-loadingangular-routerlazy-initialization

Can't resolve dynamically instantiated component when route is lazy loaded in Angular 8


I have a lazy loaded module, and I have a route like this inside the lazy loaded module:

  {
    path: 'window',
    component: CustomerFormComponent,
    canActivate: [FormGuard],
  }

I use the FormGuard to stop the navigation and open a dialog. I instantiate the component CustomerFormComponent dynamically, which is rendered in a window. Everything was working fine until I moved these routes into a new module (using loadChildren in the route) in order to lazy load the module. I am having this error because it cannot resolve the component when calling this.componentFactoryResolver.resolveComponentFactory(componentType).

ERROR Error: No component factory found for CustomerFormComponent. Did you add it to @NgModule.entryComponents?
    at noComponentFactoryError (core.js:18113)

Obviously, if I add the component in entryComponents in app.module.ts it works, but if I'm not wrong this defeats the purpose of lazy loading, doesn't it?.

What would be the correct approach?


Solution

  • No it does not.

    What entryComponents section does is explicitly tells Angular that it should keep these components' factories for further usage.

    Without specifying your dynamic components in there you are unable to make your components dynamically.

    There is even an option to lazy load modules (in similar way for components) and it also has requirements of specifying modules to be lazy loaded to keep their factories.


    Don't confuse lazy loading with dynamic instantiation.

    Dynamic loading of module makes it load when it's required (can be changed).

    Dynamic components is just an option to make your component on fly, change it and inject wherever you want without using a template.

    So if you specify your dynamic component in entry components of lazy loaded module it will work and will be loaded only when the module is loaded.

    P.S.

    If you want to lazy load some components you need to create another module. Make it lazy load. Then create a service resolver which will load this module and then resolve the components you want and do the job.