This constructor is not compatible with Angular Dependency Injection because its dependency at index 0 of the parameter list is invalid

31,236

Solution 1

We faced the same issue when migrating to version 9. At the end we found out we forgot to add decorators to some abstract components. As of v9 all classes that uses Angular DI must have an Angular class-level decorator.

Example from Ivy compatibility examples:

Before:

export class DataService {
  constructor(@Inject('CONFIG') public config: DataConfig) {}
}

@Injectable()
export class AppService extends DataService {...}

After:

@Injectable() // <--- THIS
export class DataService {
  constructor(@Inject('CONFIG') public config: DataConfig) {}
}

@Injectable()
export class AppService extends DataService {...}

Solution 2

Took me a while, but after creating a new application with angular 10.2.3 my base tsconfig.json did not have the

"emitDecoratorMetadata": true,

in the compilerOptions!

After adding that again to the tsconfig.json, DI worked as expected.

Solution 3

I've resolved my issue by adding the constructor in MyConcreteComponent and calling the super(...) constructor:

@Component({
  // ...
})
export class MyConcreteComponent extends MyAbstractComponent {

  // adding this block fixed my issue
  constructor(
    protected readonly cd: ChangeDetectorRef,
  ) {
    super(cd);
  }

  // ...
}

Solution 4

In my case simple restarting npm fixed this error.

Solution 5

In my case it happened because I was in git repository A and moved to another git repository (B) and some services which existed in repository A was no longer on B. so, by simple restarting npm this error disappeared. Hope it works for others.

Share:
31,236
Francesco Borzi
Author by

Francesco Borzi

https://github.com/FrancescoBorzi

Updated on July 09, 2022

Comments

  • Francesco Borzi
    Francesco Borzi almost 2 years

    In my Angular 9 app, I have an abstract class:

    export abstract class MyAbstractComponent {
      constructor(
        protected readonly cd: ChangeDetectorRef,
      ) {
        super();
      }
    
      // ...
    }
    

    and a Component extending it:

    @Component({
      // ...
    })
    export class MyConcreteComponent extends MyAbstractComponent {
      // ...
    }
    

    Everything works fine except the tests, where I get the following error:

    Error: This constructor is not compatible with Angular Dependency Injection because its dependency at index 0 of the parameter list is invalid. This can happen if the dependency type is a primitive like a string or if an ancestor of this class is missing an Angular decorator.

    Please check that 1) the type for the parameter at index 0 is correct and 2) the correct Angular decorators are defined for this class and its ancestors.

  • hello world
    hello world about 4 years
    hello im new to angular 9. im running into this issue but the examples arent clear to me. how do i use this in my component?
  • metodribic
    metodribic about 4 years
    Look for any component/service/directive/... in your project which are extending other component/service/directive/... and check if all of those elements has Angular class-level decorators on top of it (@Component, @Injectable, @Directive, ...)
  • briosheje
    briosheje about 4 years
    Is there any source about whether it's correct to add decorators to abstract components vs adding constructors to each extending component / service? It seems strange to me that both solutions works, although I wouldn't be surprised.
  • metodribic
    metodribic about 4 years
    I didn't find calling super on child class documented anywhere so I prefer decorators since this solution is documented as part of (advanced) migration guide
  • Vifier Lockla
    Vifier Lockla almost 4 years
    Give a template by default : @Component({ template: '<div></div>' })
  • EM-Creations
    EM-Creations about 3 years
    Same issue for me, I was really confused as to why it wasn't working, stopped npm and re-ran the ng serve command and it worked.
  • BalB
    BalB about 3 years
    In fact, it could be only added to tsconfig.spec.json, since it is only failing for test files, at least in my case...
  • ibenjelloun
    ibenjelloun almost 3 years
    I faced the same issue : moved some code from main project to a my-library. The imports where importing from the library using @my-library which works with ng serve but fails in tests. The imports must be using file path when importing same library objects.
  • Coderer
    Coderer almost 3 years
    Anybody who winds up at this answer may be interested in the discussion on this related issue on the Angular tracker.
  • Coderer
    Coderer almost 3 years
    Came down here to give this answer after discovering it for myself. I found an interesting edge case: normally, the Angular Language Service (in VSCode) flags the use of import type for DI tokens as an error. BUT, if you convert a non-injected class into an injected service without restarting the Angular language service, it seems to fail to notice that your constructor is now using DI.
  • Bohao LI
    Bohao LI over 2 years
    You are just genius.
  • shutsman
    shutsman over 2 years
    I just restarted app: run 'ng serve' again