Share Component between 2 modules

Angular

Angular Problem Overview


I'm trying to include a Component in 2 modules (parent and child) but getting various errors in the process

app.module.ts

@NgModule({
    declarations: [SharedComponent],
    exports: [SharedComponent]...
})    

child.module.ts

@NgModule({
    imports: [SharedComponent], //Unexpected directive imported by module
})  

app.html

<div class="container">
    <shared-selector></shared-selector>
    <child-selector></child-selector>
</div>

child.html

<div>
    content
    <shared-selector></shared-selector>
</div>

I'm loading the ChildModule in Async matter

loadChildren: 'app/child.module#ChildModule',

When not importing or declaring in the ChildModule I'm getting the error:

template parse error: shared-selector is not a known element

****** UPDATE *******

when Creating FeatureModule, in order to work the SharedModule should export the Components...updateed code...

SharedModule

@NgModule({
    imports: [
        CommonModule
     ],
    declarations: [
         SharedComponent
    ],
    exports: [
        SharedComponent
    ]
})

export class SharedModule {}

app.module.ts

@NgModule({
    imports: [ChildModule, SharedModule],...
})    

child.module.ts

@NgModule({
    imports: [SharedModule], //Unexpected directive imported by module
})  

Angular Solutions


Solution 1 - Angular

For completeness, according to Gunter's answer, use a SharedModule:

SharedModule

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

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

app.module.ts

@NgModule({
    imports: [ChildModule, SharedModule],...
})

child.module.ts

@NgModule({
    imports: [SharedModule]
})

Solution 2 - Angular

update

imports is only for modules, not components. I doubt it will work out if the app.module exports the shared component. Make it a SharedModule or MyFeatureModule instead and add this module to imports where you want to use the elements the module exports.

original

One component can only be added declarations of exactly one @NgModule()

As workaround create a new module for the component and add the new module to imports: [...] of the other two modules (where you want to use it).

See also https://github.com/angular/angular/issues/11481#issuecomment-246186173

> When you make a component part of a module you impart on it a set of rules when it is compiled. Having a component without belonging to a NgModule is meaningless as the compiler can't compile it. Having a component be part of more then one module is also weird as you are saying that depending which module you chose the rules for compiling are different. And when you dynamically load such a component it would be ambiguous which set of compilation rules you wanted.
> The idea of removing that each component belongs to exactly one module is a no-go for the reasons stated above.

Solution 3 - Angular

Create a SharedModule. Declare and export the SharedComponent.

shared.module.ts

 import { NgModule } from '@angular/core';
 import { CommonModule } from '@angular/common';
 import { SharedComponent } from './shared';

 @NgModule({
   declarations: [
     SharedComponent
   ],
   imports: [
     CommonModule
   ],
   exports: [
     SharedComponent
   ],
   providers: [

   ]
 })
 export class SharedModule { }

Import SharedModule in AppModule and any other Modules.

app.module.ts

  import { SharedModule } from './shared.module';
  @NgModule({
    imports: [
      SharedModule
    ]
  })

Solution 4 - Angular

You have to include the shared component in your providers: section of SharedModule. Then from derived module, you just import SharedModule, and Bingo.

    import { PagingInfoComponent } from './paging/paging.component';

   @NgModule({
      providers: [ PagingInfoComponent ],
      declarations: [ ],
      exports: [ ]
    })

   export class SharedModule {}

And, in your derived module,

import { SharedModule } from '../location/to/shared.module';
@NgModule({
 imports: [SharedModule ]
});

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionroyBView Question on Stackoverflow
Solution 1 - AngularroyBView Answer on Stackoverflow
Solution 2 - AngularGünter ZöchbauerView Answer on Stackoverflow
Solution 3 - AngularRonald DsouzaView Answer on Stackoverflow
Solution 4 - AngularirejwanulView Answer on Stackoverflow