5

I was implementing dynamic components for one of my project. The concept of dynamic components is that they come into the memory once they are needed and they have no reference in any template.

According to the official docs we declare such components in entryComponents to prevent them from getting discarded in the tree shaking process as they have no template reference.

Following is the app.module.ts where I have declared my two dynamic components SlideOneComponent and SlideTwoComponent in the entryComponents array:

  @NgModule({
  declarations: [
    AppComponent,
    ButtonComponent,
    AdDirective
  ],
  imports: [
    BrowserModule
  ],
  providers: [],
  entryComponents: [
      SlideOneComponent,
      SlideTwoComponent,
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

With above app.module.ts I am getting following error:

enter image description here

The above error fades away as soon as I add my both dynamic components to declarations array. The aforementioned official docs also says that we do not need to declare components that are reachable from entryComponents or bootstrap component. I visited this answer as well but that does not seem to be satisfactory enough as it is in reference to Ionic.

Please help me to know where I am missing on this. Thanks in advance! :)

patrick.1729
  • 4,222
  • 2
  • 20
  • 29
  • `The aforementioned official docs also says that we do not need to declare components that are reachable from entryComponents or bootstrap component.` Can you show the exact place where the doc states this? – yurzui Oct 16 '18 at 04:23
  • You must to declare any component in `declarations` array. Additionaly to this, entry components must be also declared in `entryComponents` array(NgModule or Component level) either explicity or through `bootstrap` array or rouring – yurzui Oct 16 '18 at 04:23

1 Answers1

1

As seen in this quote (while reading between the lines):

Though the @NgModule decorator has an entryComponents array, most of the time you won't have to explicitly set any entry components because Angular adds components listed in @NgModule.bootstrap and those in route definitions to entry components automatically.

You add usual components to EntryComponents array implicitly, meaning they are added in both arrays - Declarations and EntryComponents (while you added it only in Declarations array). So you must add dynamic components explicitly to both arrays as well.

Declarations purpose is to make directive (component etc.) available for other classes in your module and match it's selector with HTML.

EntryComponents tells Angular to create a componentFactory, which is being created by a compiler from the metadata you provide in @Component decorator, so you later can use it in createComponent().

As seen, these two arrays serve very different purposes and both are needed in order to create a component. If component is not created dynamically, compiler reads it's metadata and creates a componentFactory, but compiler is not aware of dynamic components, so you must inform it about dynamic components before it runs, as he runs only once - at compile time :)

Julius Dzidzevičius
  • 10,775
  • 11
  • 36
  • 81
  • But it is quite conflicting as according to docs the components declared in entryComponents are reachable and need not to be declared. The other way is to declare it in declarations array but still we need to declare it in entryComponents if it is not reachable from the components that are referenced in the template or through the components in entryComponents. So no matter what the case is I must declare in both the arrays. Am I getting it right? But still my above assumption does not clears the understanding. – patrick.1729 Oct 15 '18 at 06:42
  • Maybe you misread something or I haven't seen docs state that it "need not to be declared". I edited my answer with more details – Julius Dzidzevičius Oct 15 '18 at 11:26
  • According to docs:. "For production apps you want to load the smallest code possible. The code should contain only the classes that you actually need and exclude components that are never used. For this reason, the Angular compiler only generates code for components which are reachable from the entryComponents; This means that adding more references to @NgModule.declarations does not imply that they will necessarily be included in the final bundle.". So according to this even if we add dynamic components only to entryComponents the Angular compiler should be able to find it, is it correct? – patrick.1729 Oct 16 '18 at 10:00
  • Agree, but as it is not in the Declarations array, it's selector wont be matched with html and other classes won't be able to access it. Your erro comes from here -https://github.com/angular/angular/blob/master/packages/compiler/src/jit/compiler.ts#L227. As you see, it needs a reference to NgModel, so compiler finds your component but can't figure out where does it belong – Julius Dzidzevičius Oct 16 '18 at 16:28