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

Florian Leitgeb picture Florian Leitgeb · Sep 1, 2017 · Viewed 14.4k times · Source

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:

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?

Answer

Rahul Singh picture Rahul Singh · Sep 1, 2017

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.