Search code examples
angularangular-directive

Can't load Directive in lazy module from other NgModule


I am having a problem loading a Directive and getting the dreaded Can't bind to 'hapPluginSlot' since it isn't a known property of 'ng-container'.

In my project I have the following setup

app
  - shared
      shared.module
      - directives
          directives.module
          plugin-slot.directive
  - protected
      protected.module
      - home
          home.module (lazy loaded)
          home.component

An I have the following code in the respective files

plugin-slot.directive

@Directive({
  selector: '[hapPluginSlot]'
})
export class PluginSlotDirective {

  @Input() name: string;
  @Input() type: string;

  constructor() {
    console.log(this.name, this.type);
  }

}

directives.module

@NgModule({
  imports: [
    /* Angular Imports */
    CommonModule
  ],
  declarations: [
    PluginSlotDirective
  ],
  exports: [
    PluginSlotDirective
  ]
})
export class DirectivesModule { }

shared.module

@NgModule({
  imports: [
    /* Angular Imports */
    CommonModule,
    FormsModule,
    ReactiveFormsModule,
    ...
    /* Application Imports */
    PipesModule,
    DirectivesModule,
    ComponentsModule
  ],
  declarations: [
  ],
  exports: [
    CommonModule,
    FormsModule,
    ReactiveFormsModule,
    PipesModule,
    DirectivesModule,
    ComponentsModule,
    ...
  ]
})
export class SharedModule { }

I am importing SharedModule into my home.module as below

@NgModule({
  imports: [
    SharedModule, //<--- shared module imported here
    HomeRouterModule
  ],
  declarations: [
    HomeComponent
  ]
})
export class HomeModule { }

And using the directive in the component template as below

...
<mat-nav-list>
  <ng-container [hapPluginSlot] type="route">
  </ng-container>
</mat-nav-list>
...

And finally get to the question, I have checked and checked over this code and I am 100% certain that I have all the imports and exports in all the right places. Why am I getting this error?

I have even tried stripping back to just load the directive in the AppModule and AppComponent thinking it may be something to do with lazy loaded modules, I am clearly missing something but I cannot see the wood for the trees as I have been staring at this for what feels like an eternity.

I anyone can spot the problem then please, for the sake of the children, please point it out to me?


Solution

  • It's a syntax issue, first solution is to use your directive like this :

    <ng-container hapPluginSlot type="route"></ng-container>
    

    You could change the directive declaration to use a more compact syntax :

    @Directive({
      selector: '[hapPluginSlot]'
    })
    export class PluginSlotDirective {
       ...
       @Input('hapPluginSlot') type: string;
    

    And call it like this :

    <ng-container [hapPluginSlot]="route"></ng-container>