9

I have two Modules with components which use each other. So I have to import "word" in "test" and "test" in "word" --> throw an error... How can I do ?

Module "test":

    @NgModule({
      declarations: [
        AppTest1Component,
        AppTest2Component,
      ],
      imports: [
        AppWordModule,
      ],
      exports: [
        AppTest1Component,
        AppTest2Component,
      ],
    })
    export class AppTestModule {
    }

Module "word":

    @NgModule({
      declarations: [
        AppWordComponent,
      ],
      imports: [
        AppTestModule,
      ],
      exports: [
        AppWordComponent,
      ],
    })
    export class AppWordModule {
    }

I import each other because of the template. The template of test1.component.ts calls word.component.ts et the template of word.component.ts calls test1.component.ts.

test1.html

    <div class="app-word"></div>

word.html

    <div class="app-test1"></div>

I tried to use a SharedModule but I don't achieve it...

5
  • 1
    You can't have a circular dependency. You'll need to break up at least one of the modules to break that circular dependency. Commented Sep 18, 2018 at 18:31
  • 1
    It seems a bad architecture. Why the module A needs the module B and the module B needs A ?
    – JFPicard
    Commented Sep 18, 2018 at 18:32
  • You code is creating circular dependency. Import both module into appmodule. and remove import module from both module Commented Sep 18, 2018 at 18:37
  • 1
    Yes I know it's circular dependency... The architecture is quite complex so I don't really have the choice. I tried to import them both in a parent module (app module) but it doesn't works : "[...] it isn't a known property of 'app-word'"
    – MatDepInfo
    Commented Sep 19, 2018 at 9:55
  • 1
    Why not create a SharedModule with both components and then import the sharedmodule in both test and word modules? That will work.
    – Karthik RP
    Commented May 21, 2020 at 4:30

2 Answers 2

3
+25

Maybe you can use content projection with ng-content directive to compose nested components, but it depends how you need to compose them, in example

// ComposeModule

    @NgModule({
      imports: [
        CommonModule,
        AppWordModule,
        AppTestModule
      ],
      declarations: [CompositionComponent],
      exports: [CompositionComponent]
    })
    export class ComposeModule { }

// composition.component.html

    <app-word>
      <app-child-one header>
        <app-word body>
        </app-word>
      </app-child-one>
      
      <app-child-two body>
        <app-word body>
        </app-word>
      </app-child-two>
    </app-word>

// AppWordModule

    @NgModule({
      imports: [
        CommonModule
      ],
      declarations: [ WordComponent ],
      exports: [ WordComponent ]
    })
    export class AppWordModule { }

// word.component.html

    <div class="header">
      <h2>app-word:header</h2>
      <ng-content select="[header]"></ng-content>
    </div>
    <div class="body">
      <h2>app-word:body</h2>
      <ng-content select="[body]"></ng-content>
    </div>

// AppTestModule

    const COMPONENTS = [
      ChildOneComponent,
      ChildTwoComponent
    ]
    
    @NgModule({
      imports: [
        CommonModule
      ],
      declarations: [
        ...COMPONENTS
      ],
      exports: [
        ...COMPONENTS
      ]
    })
    export class AppTestModule { }

// child-one.component.html

    <div class="header">
      <h2>app-child-one:header</h2>
      <ng-content select="[header]"></ng-content>
    </div>
    <div class="body">
      <h2>app-child-one:body</h2>
      <ng-content select="[body]"></ng-content>
    </div>

// child-two.component.html

    <div class="header">
      <h2>app-child-two:header</h2>
      <ng-content select="[header]"></ng-content>
    </div>
    <div class="body">
      <h2>app-child-two:body</h2>
      <ng-content select="[body]"></ng-content>
    </div>
2

You need to solve the problem architecturally.

You can either create a module that has both functionalities ... since they seem so closely coupled, it would be my first preference, or else you can break up the modules even more so that the features of one module that are required by the other are in their own module.

Not the answer you're looking for? Browse other questions tagged or ask your own question.