6

I created an internal directive in a module in my project (Angular 8 + Material Design). Following tuto and official doc.

@Directive({
  selector: '[button-confirmation]'
})
export class ButtonConfirmationDirective {

  @Output('bc-confirm')
  confirmAction = new EventEmitter<any>();

  @Input('bc-options')
  options: Option[] = [...];

  constructor(
    private el: ElementRef,
    private confirmationService: ConfirmationService
  ) { }

  @HostListener('mouseup') onMouseUp() {
    this.confirmationService.displayConfirm(this.el, this.options, this.confirmAction);
  }

}

Ok, it's work. BUT, when i create an external library and move my directive (with components, services, ...) i got the error :

ERROR NullInjectorError: "StaticInjectorError(AppModule)[ButtonConfirmationDirective -> ElementRef]: 
  StaticInjectorError(Platform: core)[ButtonConfirmationDirective -> ElementRef]: 
    NullInjectorError: No provider for ElementRef!"

The lib created from a ng new fop-common -S followed by ng g library fop-common then i cleaned my lib folder keeping the module.ts and adding my directive/components/services...

The button-confirmation.module.ts

@NgModule({
  declarations: [
    ButtonConfirmationComponent,
    ButtonConfirmationDirective
  ],
  imports: [
    CommonModule,

    MatButtonModule,
    MatIconModule,
    MatTooltipModule
  ],
  providers: [
    ConfirmationService,
    DomService
  ],
  exports: [
    ButtonConfirmationComponent,
    ButtonConfirmationDirective
  ],
  entryComponents: [
    ButtonConfirmationComponent
  ]
})
export class ButtonConfirmationModule { }

The fop-common.module.ts looks like

@NgModule({
  declarations: [
    JoinPipe
  ],
  imports: [],
  exports: [
    JoinPipe,
    ButtonConfirmationModule
  ]
})
export class FopCommonModule { }

And in my project, i import it

  imports: [
...
    FopCommonModule
  ],

For the installation of the lib i used the local way (private project without npm) : npm install ../fop-common/dist/fop-common --save

I already have interfaces and pipes working, so globally it's working, but just have the ElementRef problem, but found nothing for this case (except old solution for < 8 with symlink parameter, but not working off course).

Any help appreciate. Thanks in advance.

Killan
  • 321
  • 1
  • 6
  • 14
  • Could you show us how you've defined the `ButtonConfirmationModule` class? Did you include the necessary modules that `ButtonConfirmationModule` uses (e.g. `CommonModule` from `@angular/core`, etc.)? – Edric Aug 23 '19 at 14:07
  • 1
    Hi, i add it to the question. CommonModule is in. And for repeat, if it's not in the external lib, but in the project, it's works well. Don't hesitate if you need more. Thanks – Killan Aug 23 '19 at 14:13
  • Following other tuto, I tried too to expose directly the ButtonConfirmationModule but result is the same. – Killan Aug 24 '19 at 12:29

5 Answers5

5
"paths": {
    "@angular/*": [
        "./node_modules/@angular/*"
    ]
}

Make the paths mapping in the application's tsconfig (where you are linking to the library) and not the library one.

Ashwani Kumar
  • 216
  • 2
  • 14
1

For the installation of the lib i used the local way (private project without npm) : npm install ../fop-common/dist/fop-common --save

Usually you do not have to do this. When you did ng g library fop-common, it should have created an alias path in your tsconfig.json in the project and you just need to import your lib using import {...} from 'fop-common';

I'm not sure it's the problem but I already had some issues when trying to install dependencies locally.

yon
  • 11
  • 1
  • Hi Yon, the goal is to build a separate lib, not to have this lib in the projects workspace, i created different apps in different git repo, all is separate. Maybe you know a way like this ? – Killan Aug 26 '19 at 20:48
1

You add this in tsconfig.ts in compilerOptions:

  "paths": {
      "@angular/*": [
        "./node_modules/@angular/*"
      ]
    }
Chrism
  • 11
  • 1
0

No solution found.

I put back the code (only, not the lib context) in the project instead of make a lib, but i separate both git repo for reuse.

So the trick is to add a postinstall script to create a /src/libsubfolder with the "lib" repo inside (git clone), edit the main project .gitignore to add this libsubfolder and you have a "working" trick solution.

For more ease i edited the tsconfig.json to add a paths config to map libsubfolder for all import through the main project.

So i avoid all projects inside a same repo (angular /projects folder), i make it maintainable and reusable and easy to put in place and each has its own repo. So it's ok for me.

Thanks for who's tried to help.

Killan
  • 321
  • 1
  • 6
  • 14
  • I had a similar error and resolved it by just restarting the server, this was after adding dependency injection to a class file. – Daniel Jul 08 '20 at 02:30
0

I got this NullInjector error when trying to use a UI control from a shared library module, adding the @angular path to my applicaiton's tsconfig.json solved the issue. Same as Ashwani Kumar suggested.

"paths": {
    "@angular/*": [
        "./node_modules/@angular/*"
    ]
}
JLI
  • 11
  • 3