I'm little bit confused in this two scenarios, we mark some classes with @Injectable() decorator so that they become available for injection to different components. I just want to know What is the difference between @Inject() and constructor injection as normal.
Scenario 1 - Using @Inject() :
@Component({
selector: 'main-app',
template: `
....
{{_service.getName()}}
....
`
})
export class AppComponent{
constructor(@Inject(AppService) private _service){}
....
}
Scenario 2 - Using as a Normal parameter :
@Component({
selector: 'main-app',
template: `
....
{{_service.getName()}}
`
})
export class AppComponent{
constructor(private _service:AppService){}
....
}
Both scenarios are working, is there any difference ? which one should is more preferable ?
You really should only use @Inject
for situations where the injectable token is not a class. If you are unfamiliar with what a token is, it is basically what Angular uses to recognize what to inject. For example
providers: [
AuthService,
{ provide: Http, useValue: new CustomHttpImpl() }
]
Here we have two different providers, the AuthService
and the CustomHttpImpl
. With the AuthService
the token is AuthService
. This means that we inject AuthService
, using obviously the AuthService
type
constructor(private authService: AuthService) {}
With this constructor, Angular knows to look for the AuthService
with the token AuthService
.
In the second provider, we provide a CustomHttpImpl
but this time we use the token Http
. So we cannot inject CustomHttpImpl
we need to inject Http
, since that is the token
// this will actually be the CustomHttpImpl, not Angular's Http
constructor(private http: Http)
// error: No provider for CustomHttpImpl
constructor(private http: CustomHttpImpl)
So you can tell from this that the tokens are all classes, which is enough for Angular to figure out to how to inject.
But let's say we have a String, or an Array of something we want to inject. We can't tie that to any class token, so we need to create an artificial token
import { OpaqueToken } from '@angular/core';
let numbers = [ 1, 2, 3, 4 ];
let config = '{ "some": "json", "config": "data" }'
const NUMBERS = new OpaqueToken('app.numbers');
const CONFIG = new OpaqueToken('app.config');
Now we have tokens for the items we want to inject. When we configure the providers
, we use those tokens, and when we inject, we @Inject(TOKEN)
providers: [
{ provide: NUMBERS, useValue: numbers },
{ provide: CONFIG, useValue: config }
]
constructor(@Inject(NUMBERS) numbers: number[], @Inject(CONFIG) config: string)
Now, with Angular 4, we should use InjectionToken
rather than OpaqueToken
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With