2

I have a simple service in Angular

// service.ts
export class SimpleService {
    // ...
}

// component.ts
@Component({
    selector: 'my-component',
    templateUrl: 'components/mycomp/mycomp.html',
    providers: [
        SimpleService
    ]
})
class MyComponent {
    constructor(private ss: SimpleService) {}
}

This above code never works. I get an error: Uncaught Error: Can't resolve all parameters for MyComponent: (?).

However, if I change my constructor definition to:

class MyComponent {
    constructor(@Inject(SimpleService) private ss: SimpleService) {}
}

Then it works. Even documentation doesn't seem to use @Inject. From the documentation I understand that @Inject is explicitly required when my provider token is not class; like, trying to inject primitive values, or using opaque tokens, etc.

Also, I am confused in regards to typescript. Official documentation clearly mentions that when @Inject() is not present, Injector will use the type annotation of the parameter. If type information is erased during typescript transpilation and DI is happening when app is running, how can Angular use type annotation at runtime? Is there anything I am missing?

Arashsoft
  • 2,749
  • 5
  • 35
  • 58
Harshal Patil
  • 17,838
  • 14
  • 60
  • 126
  • 1
    did you add the service as a provider to the component – Sachila Ranawaka May 22 '17 at 04:09
  • 1
    Well preferably that would be the scoped `NgModule` that includes the component in declarations. But the point is unless the `@Injectable` service is registered as a `provider` somewhere then it will not be available without an explicit reference. – Neil Lunn May 22 '17 at 04:12
  • @sachilaranawaka yes, I tried both NgModule and providers for component – Harshal Patil May 22 '17 at 04:13
  • @NeilLunn, you are suggesting if I should try adding `@Injectable` as provider in my module. I don't see it anywhere documented. – Harshal Patil May 22 '17 at 04:17
  • Show us your tsconfig.json – yurzui May 22 '17 at 04:22
  • show the full `@Component({...})` – Sachila Ranawaka May 22 '17 at 04:23
  • @yurzui Here is the tsconfig.json `{ "compilerOptions": { "outDir": "./dist/", "sourceMap": true, "experimentalDecorators": true, "lib": ["es2017", "dom"], "module": "es2015", "moduleResolution": "Node", "target": "es5" }, "include": [ "src/**/*" ], "exclude": [ "node_modules", "dist" ] }` – Harshal Patil May 22 '17 at 04:25
  • You have the ability to [Edit](http://stackoverflow.com/posts/44104517/edit) your question. Please stop posting additional details in comments and make "edits" to your question instead. – Neil Lunn May 22 '17 at 04:26
  • 2
    http://stackoverflow.com/questions/39602890/angularjs-2-0-cant-inject-anything-through-component-constructor/39608530#39608530 – yurzui May 22 '17 at 04:28
  • @yurzui That did the trick. My `tsconfig.json` was missing `"emitDecoratorMetadata": true` – Harshal Patil May 22 '17 at 04:35

1 Answers1

3

You forgot to add

"emitDecoratorMetadata": true

to your tsconfig.json

See also

Community
  • 1
  • 1
yurzui
  • 205,937
  • 32
  • 433
  • 399