NullInjectorError: No provider for ElementRef
Asked Answered
E

5

7

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.

Extramural answered 23/8, 2019 at 12:35 Comment(3)
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.)?Propaedeutic
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. ThanksExtramural
Following other tuto, I tried too to expose directly the ButtonConfirmationModule but result is the same.Extramural
E
1

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.

Extramural answered 24/9, 2019 at 7:9 Comment(1)
I had a similar error and resolved it by just restarting the server, this was after adding dependency injection to a class file.Carney
M
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.

Mertens answered 19/12, 2019 at 15:59 Comment(1)
it works with StaticInjectorError(Platform: core)[NgClass -> ElementRef]: Henderson
M
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.

Micromillimeter answered 26/8, 2019 at 19:50 Comment(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 ?Extramural
E
1

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.

Extramural answered 24/9, 2019 at 7:9 Comment(1)
I had a similar error and resolved it by just restarting the server, this was after adding dependency injection to a class file.Carney
G
1

You add this in tsconfig.ts in compilerOptions:

  "paths": {
      "@angular/*": [
        "./node_modules/@angular/*"
      ]
    }
Giles answered 3/11, 2019 at 19:34 Comment(0)
B
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/*"
    ]
}
Bespoke answered 29/4, 2020 at 22:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.