Use component from AppModule in a child module in Angular X (X stands for 2+)
Asked Answered
T

2

15

I have created a small component (LoadingComponent) in the root of my application and declared it (obviously) in my AppModule. This component is used when my application is loading and should show some fancy loading animations.

Now I want to use it in a child module when I save something. But I am always getting errors when I want to use this component in another module.

I exported the LoadingComponent in my AppModule:

import { ButtonsModule } from './buttons/buttons.module';
import { FormsModule } from '@angular/forms';
import { StatusLightsDisplayComponent } from './status-lights-display/status-lights-display.component';
import { StatusLightsContainerComponent } from './status-lights-container/status-lights-container.component';
import { HttpModule } from '@angular/http';
import { ReportsService } from './services/reports.service';
import { BrowserModule } from '@angular/platform-browser';
import { forwardRef, NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { GeneralInformationComponent } from './general-information/general-information.component';
import { TextfieldsComponent } from './textfields/textfields.component';
import { LoadingComponent } from './loading/loading.component';

@NgModule({
  declarations: [
    AppComponent,
    GeneralInformationComponent,
    TextfieldsComponent,
    StatusLightsContainerComponent,
    StatusLightsDisplayComponent,
    LoadingComponent
  ],
  imports: [
    BrowserModule,
    HttpModule,
    FormsModule,
    ButtonsModule
  ],
  exports: [
    LoadingComponent
  ],
  providers: [
    ReportsService
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

The module I want to use the LoadingComponent is called ButtonsModule. So I tried to import the AppModule in my ButtonsModule. But I am getting the error: Unexpected value 'undefined' imported by the module 'ButtonsModule'

Here is my ButtonsModule:

import { AppModule } from '../app.module';
import { LoadingComponent } from '../loading/loading.component';
import { BottomComponent } from './bottom/bottom.component';
import { CalendarComponent } from './top/calendar/calendar.component';
import { CommonModule } from '@angular/common';
import { ExportService } from '../services/export.service';
import { forwardRef, NgModule } from '@angular/core';
import { FunctionsComponent } from './functions/functions.component';
import { NavArrowsComponent } from './shared/nav-arrows/nav-arrows.component';
import { SaveButtonComponent } from './shared/save-button/save-button.component';
import { TopComponent } from './top/top.component';

@NgModule({
  imports: [
    CommonModule,
    AppModule
  ],
  exports: [
    TopComponent,
    FunctionsComponent,
    BottomComponent
  ],
  declarations: [
    TopComponent,
    BottomComponent,
    FunctionsComponent,
    NavArrowsComponent,
    SaveButtonComponent,
    CalendarComponent
  ],
  providers: [
    ExportService
  ]
})
export class ButtonsModule { }

I guess some of you already recognize some fail here :) But please read it to the end.

I know the best practice here would be to create a shared module and then import this in my AppModuleand the ButtonsModule, but this seems to be a little overkill, just for such a small component and it would also be my only shared module here. It would also create a lot of overhead.

My questions:

  • Am I doing something wrong here? If yes, what is it?
  • Would be the way, by creating a shared module, the right one?
  • Why is my approach not working? I mean, what is forbidding my approach under the hood of Angular and why?
Toehold answered 1/9, 2017 at 10:55 Comment(11)
doing something like this completely removes the benifits of lazy loading you have to use a shared module for this too bad but its for the modularityDunsany
But I am not using lazy loading. So it is not possible to use components from my AppModule in different modules in my app? Why is it so?Toehold
whya re you importing the app module just the buttons module will then do the trickDunsany
Sorry but I do not understand your question. I am importing the AppModule, because otherwise it is not possible to use the same component in two different modules.Toehold
ohh yes my bad , that is where shared modules comes in picture , the problem is that everything compiles down to the mail app module importing it again makes a kind of circular dependency that is reason it guess it doesn't work.Dunsany
But in this case, it would make sense to have as few as possible components in your AppModule and pack them at least in one big child module. Or am I missing something?Toehold
yes it depends on how your app is divided in module'sDunsany
Am I right that the AppModule will never have an export array declared?Toehold
Yes AppModule is like the main module and should not have a exportDunsany
It would be awesome, if you could summarize this as an answer. Just for other users who also want to understand this and to give you some points ;)Toehold
Updated hope it helps othersDunsany
D
15

NgModules help organize an application into cohesive blocks of functionality.

Every Angular app has a root module class. By convention, the root module class is called AppModule and it exists in a file named app.module.ts.

What if I import the same module twice?

That's not a problem. When three modules all import Module 'A', Angular evaluates Module 'A' once, the first time it encounters it, and doesn't do so again.

That's true at whatever level A appears in a hierarchy of imported modules. When Module 'B' imports Module 'A', Module 'C' imports 'B', and Module 'D' imports [C, B, A], then 'D' triggers the evaluation of 'C', which triggers the evaluation of 'B', which evaluates 'A'. When Angular gets to the 'B' and 'A' in 'D', they're already cached and ready to go.

Angular doesn't like modules with circular references, so don't let Module 'A' import Module 'B', which imports Module 'A'.

Link

Everything at the end compiles down to the Main App Module and importing it again in same module make the above condition true of circular dependency. And being the main Module it should ideally not have any exports to be used by other Modules.

Dunsany answered 1/9, 2017 at 12:36 Comment(0)
K
4

Make a components module whose only job is to gather up the components, and export them, and import it in both places. At first it seems painful but then you realize it helps to organize what is used where and will scale.

Keen answered 19/10, 2017 at 19:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.