When I create a new page component, I now have to place it in declarations as well as entryComponents Array. Why does it have to be at both the places ?
e.g I just created a new login.page.ts file, but i have to declare it in both declarations and entryComponents array (btw its not a entryComponent so to speak)
app.module.ts
@NgModule({
declarations: [
MyApp,
LoginPage
],
imports: [
IonicModule.forRoot(MyApp),
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
LoginPage
],
providers: [{provide: ErrorHandler, useClass: IonicErrorHandler}]
})
export class AppModule {}
The reason for entryComponents
is nicely explained in this blog entry:
In the entryComponents
section we define any component that is only loaded by its type. This is the case for all Page components since these are all loaded through the Navigation Controller.
Components that are loaded declaratively (i.e. are referenced in another component's template) don't need to be included in the entryComponents
array.
So as you can see we have some duplication where we have to define our Page components in both the declarations and the entryComponents
sections. The reason for having this separate entryComponents
section is so that Angular can compile a bundle for the app that will only include the components that are actually used within the app.
The least we can try is to avoid code duplication.
There's not much freedom for dynamic code in the annotations. Trying generate entryComponents
using an expression like
const myComponents = [
MyComponent
]
const myPages = [
MyApp,
LoginPage
]
@NgModule({
entryComponents: myComponents.concat(myPages),
/* ... */
})
will result in:
Error: Error encountered resolving symbol values statically.
Function calls are not supported.
Consider replacing the function or lambda with a reference to an exported function
Trying to use an exported function like this
export function getEntryComponents() { return [ /* ... */ ] }
@NgModule({
entryComponents: getEntryComponents,
/* ... */
})
results in:
Error: Error encountered resolving symbol values statically.
Expression form not supported
Fortunately there is a solution. You can use array spread operator here:
@NgModule({
declarations: [
...myComponents,
...myPages
],
entryComponents: myPages
/* ... */
})
Placing an entryComponent should really not be required if the rest of your application is configured properly.
Angular adds certain components to entry components automatically.
Components listed in @NgModule.bootstrap
are added automatically.
Components referenced in router configuration
are added automatically.
These two mechanisms account for almost all entry components.
If your app happens to bootstrap or dynamically load a component by
type in some other manner, you'll have to add it to entryComponents
explicitly.
Although it's harmless to add components to this list, it's best to
add only the components that are truly entry components. Don't include
components that are referenced in the templates of other components.
From: https://angular.io/docs/ts/latest/cookbook/ngmodule-faq.html#!#q-when-entry-components