Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve error message for when Injectable() is missing #12467

Closed
JPtenBerge opened this issue Oct 23, 2016 · 4 comments
Closed

Improve error message for when Injectable() is missing #12467

JPtenBerge opened this issue Oct 23, 2016 · 4 comments
Labels
area: compiler Issues related to `ngc`, Angular's template compiler area: core Issues related to the framework runtime freq3: high hotlist: error messages type: bug/fix
Milestone

Comments

@JPtenBerge
Copy link

JPtenBerge commented Oct 23, 2016

I'm submitting a ...

[x] bug report

Current behavior
If component A has a dependency on service B, but service B does not have the Injectable() decorator defined, a vague error message is thrown:

Can't resolve all parameters for SomeService: (?, ?)

This is the exact same error message for when dependencies can't be loaded. Up until now that error message was given because I use barrel files and the order of import/exports should be adjusted. Thus, I was thrown off when trying to fix this problem.

Expected behavior
A specific error message like:

SomeService was provided, but an `Injectable()` decorator was not found

Minimal reproduction of the problem with instructions

  • Create a service, but omit the Injectable() decorator. This service should have a dependency to at least one other service (defined correctly).

    import { Injectable } from '@angular/core';
    
    // oops, forgot the decorator
    export class SomeService {
      constructor(private otherService: OtherService) { }
    }
    
    @Injectable()
    export class OtherService { }
    
  • Provide the services with the module.

  • Create a component that gets the SomeService injected.

I used the Plnkr of the Angular quickstart to reproduce this problem. On the Car service in app/car/car.ts, I simply removed the decorator. The console immediately shows the error:

Can't resolve all parameters for Car: (?, ?)

// Edit:
In the documentation, it is mentioned that the injector will throw a NoAnnotationError, but the link to NoAnnotationError results in a 404.

What is the motivation / use case for changing the behavior?
A more precise error message would direct me to the problem instantly and the problem could have been fixed in a matter of seconds. Because this message is the exact same as when dependencies can't be resolved due to import/export order with barrel files, it now took me 30 minutes of stripping dependencies and order checking before I noticed this simple and tiny mistake.

Please tell us about your environment:
Windows 10, Chrome 53 and SystemJS as the module loader.

  • Angular version: 2.0.0 and upwards. It is still a problem in 2.1.0.
  • Browser: The web application crashes in all browsers. Chrome 53 and Edge 38 clearly show the error in the console. Firefox however, shows a CompileMetadataResolver and I'm not able to find a more specific error message.
  • Language: TypeScript 2.0.3.
  • Node (for AoT issues): 6.0.0.
@pkozlowski-opensource pkozlowski-opensource added hotlist: error messages area: core Issues related to the framework runtime labels Oct 23, 2016
DzmitryShylovich pushed a commit to DzmitryShylovich/angular that referenced this issue Dec 17, 2016
DzmitryShylovich pushed a commit to DzmitryShylovich/angular that referenced this issue Dec 17, 2016
DzmitryShylovich added a commit to DzmitryShylovich/angular that referenced this issue Mar 4, 2017
DzmitryShylovich added a commit to DzmitryShylovich/angular that referenced this issue Mar 5, 2017
BREAKING CHANGE:

Before:

class SomeService {}

@component({selector: 'my-app', template: ''})
class AppComponent {
  constructor(service: SomeService) {}
}

After:

@Injectable()
class SomeClass {}

@component({selector: 'my-app', template: ''})
class AppComponent {
  constructor(service: SomeService) {}
}

Closes angular#12467
Closes angular#13820
DzmitryShylovich added a commit to DzmitryShylovich/angular that referenced this issue Mar 5, 2017
BREAKING CHANGE: Before this commit it was not nessesary to add
@Injectable for contructors without args or if any other decorator was
applied. After this commit @Injectable is mandatory for all providers
provided using useClass.

Before:

class SomeService {}

@component({selector: 'my-app', template: ''})
class AppComponent {
  constructor(service: SomeService) {}
}

After:

@Injectable()
class SomeClass {}

@component({selector: 'my-app', template: ''})
class AppComponent {
  constructor(service: SomeService) {}
}

Closes angular#12467
Closes angular#13820

feat(compiler): wip

feat(compiler): wip

feat(compiler): wip
DzmitryShylovich added a commit to DzmitryShylovich/angular that referenced this issue Mar 5, 2017
BREAKING CHANGE: Before this commit it was not nessesary to add
@Injectable for contructors without args or if any other decorator was
applied. After this commit @Injectable is mandatory for all providers
provided using useClass.

Before:

class SomeService {}

@component({selector: 'my-app', template: ''})
class AppComponent {
  constructor(service: SomeService) {}
}

After:

@Injectable()
class SomeService {}

@component({selector: 'my-app', template: ''})
class AppComponent {
  constructor(service: SomeService) {}
}

Closes angular#12467
Closes angular#13820

feat(compiler): wip

feat(compiler): wip

feat(compiler): wip

feat(compiler): wip
DzmitryShylovich added a commit to DzmitryShylovich/angular that referenced this issue Mar 5, 2017
BREAKING CHANGE: Before this commit it was not nessesary to add
@Injectable when a service had contructor without args or if any other decorator was
applied. After this commit @Injectable is mandatory for all services
provided using useClass.

Before:

class SomeService {}

@component({selector: 'my-app', template: ''})
class AppComponent {
  constructor(service: SomeService) {}
}

After:

@Injectable()
class SomeService {}

@component({selector: 'my-app', template: ''})
class AppComponent {
  constructor(service: SomeService) {}
}

Closes angular#12467
Closes angular#13820
DzmitryShylovich added a commit to DzmitryShylovich/angular that referenced this issue Mar 5, 2017
BREAKING CHANGE: Before this commit it was not nessesary to add
@Injectable when a service had contructor without args or if any other decorator was
applied. After this commit @Injectable is mandatory for all services
provided using useClass.

Before:

class SomeService {}

@component({selector: 'my-app', template: ''})
class AppComponent {
  constructor(service: SomeService) {}
}

After:

@Injectable()
class SomeService {}

@component({selector: 'my-app', template: ''})
class AppComponent {
  constructor(service: SomeService) {}
}

Closes angular#12467
Closes angular#13820
DzmitryShylovich added a commit to DzmitryShylovich/angular that referenced this issue Mar 5, 2017
BREAKING CHANGE: Before this commit it was not nessesary to add
@Injectable when a service had contructor without args or if any other
decorator was applied. After this commit @Injectable is mandatory for
all services provided using useClass.

Before:

class SomeService {}

@component({selector: 'my-app', template: ''})
class AppComponent {
  constructor(service: SomeService) {}
}

After:

@Injectable()
class SomeService {}

@component({selector: 'my-app', template: ''})
class AppComponent {
  constructor(service: SomeService) {}
}

Closes angular#12467
Closes angular#13820
DzmitryShylovich added a commit to DzmitryShylovich/angular that referenced this issue Mar 12, 2017
BREAKING CHANGE: Before this commit it was not nessesary to add
@Injectable when a service had contructor without args or if any other
decorator was applied. After this commit @Injectable is mandatory for
all services provided using useClass.

Before:

class SomeService {}

@component({selector: 'my-app', template: ''})
class AppComponent {
  constructor(service: SomeService) {}
}

After:

@Injectable()
class SomeService {}

@component({selector: 'my-app', template: ''})
class AppComponent {
  constructor(service: SomeService) {}
}

Closes angular#12467
Closes angular#13820
DzmitryShylovich added a commit to DzmitryShylovich/angular that referenced this issue Mar 12, 2017
BREAKING CHANGE: Before this commit it was not nessesary to add
@Injectable when a service had contructor without args or if any other
decorator was applied. After this commit @Injectable is mandatory for
all services provided using useClass.

Before:

class SomeService {}

@component({selector: 'my-app', template: ''})
class AppComponent {
  constructor(service: SomeService) {}
}

After:

@Injectable()
class SomeService {}

@component({selector: 'my-app', template: ''})
class AppComponent {
  constructor(service: SomeService) {}
}

Closes angular#12467
Closes angular#13820
@ngbot ngbot bot added this to the Backlog milestone Jan 23, 2018
@codegagan
Copy link

This issue I have faced in current angular cli version 1.7

@bigteejay
Copy link

bigteejay commented May 23, 2018

Same, while injecting ActivatedRoute into my component. Is ActivatedRoute missing its @Inject?

PS: Hmm... Router doesn't seem to have it either (and I can inject that just fine.)

I'll look into creating a new issue (if one regarding this doesn't exist already.)

PPS: Reloading vscode (CTRL+SHIFT+P, "relo", ENTER) made the error go away (and it builds without issue.)

@pkozlowski-opensource
Copy link
Member

The error message is much more specific with Angular v9 running ivy, ex.:

Error
src/app/app.module.ts(20,15): error TS-992005: The class 'SomeService' cannot be created via dependency injection, as it does not have an Angular decorator. This will result in an error at runtime.
Either add the @Injectable() decorator to 'SomeService', or configure a different provider (such as a provider with 'useFactory').

https://ng-run.com/edit/d0NblIE4tkjFnxSyKZFU

@pkozlowski-opensource pkozlowski-opensource added the area: compiler Issues related to `ngc`, Angular's template compiler label Mar 10, 2020
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Apr 10, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: compiler Issues related to `ngc`, Angular's template compiler area: core Issues related to the framework runtime freq3: high hotlist: error messages type: bug/fix
Projects
None yet
5 participants