Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Placing components in declarations array as well as entryComponents array

Tags:

angular

ionic2

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 {}
like image 879
runtimeZero Avatar asked Nov 26 '16 15:11

runtimeZero


People also ask

What is the difference between declarations and entryComponents?

Difference between entry Component and Declaration: entryComponents are used to register components for offline computation in a module. These components are referenced here as they not referenced anywhere else in HTML template. Declarations are used to make Directives(components, pipes etc.) in a specific module.

Is entryComponents deprecated?

Entry components are deprecated, for more information, see entryComponents deprecation in the Deprecated APIs and features. An entry component is any component that Angular loads imperatively, (which means you're not referencing it in the template), by type.

Which of the following components list dynamically loaded into the View Options bootstrap providers declarations entryComponents?

A bootstrap component is automatically added to entryComponents. A list of components that can be dynamically loaded into the view.

What kind of items belong in the declarations array of an Angular module?

The declarations array is used to declare components, directives, and pipes into the module in which they belong. Every component, directive, and pipe gets to know about others through this declaration.


1 Answers

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
 /* ... */
})
like image 77
rzymek Avatar answered Sep 19 '22 22:09

rzymek