John
John

Reputation: 1888

Imported Module is undefined Angular4

Very new to Angular so this is probably a setup issue. But I have a module that is undefined when I try and import it into another module and I think it has to do with the order because when I switch it the other module can't be imported.

My tree looks like this

|-- src/
|   |-- app/
|   |   |-- components/
|   |   |   |-- login/
|   |   |   |   |-- login.compact.component.html
|   |   |   |   |-- login.component.html
|   |   |   |   |-- login.component.ts
|   |   |   |   |-- login.service.ts
|   |   |   |   |-- login.module.ts
|   |   |   |-- ...
|   |   |   |-- components.module.ts
|   |   |-- shared/
|   |   |   |-- header/
|   |   |   |-- footer/
|   |   |   |-- navigation/
|   |   |   |-- shared.module.ts
|   |   |-- app.component.html
|   |   |-- app.component.ts
|   |   |-- app.module.ts
|   |   |-- app.routes.ts

I was trying to add a compact version of login to my navigation bar

navigation.component.html

<nav>
   ....
   <mylogin></mylogin>
</nav>

But when I add the LoginModule to the imports of the SharedModule I get this errror Unexpected value 'undefined' imported by the module 'LoginModule'

In my app.module.ts I have

import {SharedModule} from './shared/shared.module';

import {ComponentsModule} from './components/components.module';
....
@NgModule({
declarations: [
    AppComponent,
],
imports: [
    BrowserModule,
    FormsModule,
    HttpClientModule,
    SharedModule,
    ComponentsModule,
    BsDropdownModule.forRoot(),
    RouterModule.forRoot(
        APP_ROUTES,
        {enableTracing: true})
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {
}

Is this a bad way to structure the app? Or is it wrong to try and import login into the shared module to use in navigation?

Upvotes: 1

Views: 2254

Answers (1)

Prav
Prav

Reputation: 2884

First of all, I don't know how you have imported the LoginModule into SharedModule as you haven't provided the SharedModule.

Secondly, if you wish to import one module into another module. You need to add exports: [] with all the declarations that you want to import to the other module. Here's an example:

Module A

@NgModule({
  imports: [
    CommonModule
  ],
  declarations: [
    CapitalizePipe,
    SentenceCasePipe,
    FirstNamePipe,
  ],
  exports: [
    CapitalizePipe,
    SentenceCasePipe,
    FirstNamePipe,
  ]
})
export class PipesModule {
}

Module B that imports Module A

@NgModule({
  imports: [
    CommonModule,
    FormsModule,
    PipesModule,
    NgbModule,
    RouterModule,
    AppRoutingModule
  ],
  declarations: [],
  providers: []
})
export class HomeModule {
}

As you can see, the PipesModule from module A is imported into module B by adding all the declarations in the exports: []; which allows them to be able to load on to different modules on demand.

FYI

Adding things to the AppModule will result in all of those things to be loaded into the browser DOM on application load. That means if you add modules that are only used in one component; this can result in your application's load time to extend as it needs to all the modules.

So my advice to you is to plan your app as much nested style as possible with incremental module loading, making your app loads faster and smoother. An example would be:

AppModule
AppComponent
   | PublicModule
   | PublicComponent
         | LoginModule
         | LoginComponnet
                | HomeModule
                | HomeComponent

Upvotes: 1

Related Questions