5

I have a component that uses a service. The component looks something like this:

@Component({
    moduleId: module.id,
    selector: 'test',
    providers: [HTTP_PROVIDERS, TestService]
})
export class TestComponent implements OnInit {

    constructor(private _testService:TestService) {
    }

As you can see, I added the HTTP_PROVIDERS provider in my component. This worked since the DI is now aware of the http classes. However, it was my TestService that was really using the Http class, not my TestComponent.

@Injectable()
export class TestService {

    constructor(private _http:Http) {
    }

I felt that since it is the service using the Http class, it should be the one including the providers in itself. The TestComponent wouldn't know what providers TestService would need.

Since the service class doesn't have that component decorator, I'm not sure how I can actually add providers to it. How can I add providers to a Service class?

Carven
  • 14,988
  • 29
  • 118
  • 161

1 Answers1

3

What you can do is,

Inject HTTP_PROVIDERS into bootstrap function ,

import {HTTP_PROVIDERS} from '@angular/http';
bootstrap(AppComponent,[HTTP_PROVIDERS]);

and in your service,

import {Http} from '@angular/http';

@Injectable()
export class TestService {
    constructor(private _http:Http) {}
}
micronyks
  • 54,797
  • 15
  • 112
  • 146
  • 1
    Maybe it's still reasonable to put `HTTP_PROVIDERS` in the bootstrap function since it is used quite often. But what if it was some other classes that is only used in this service? It wouldn't be very good to include it on every page through the bootstrap function. Would it be better if the provider is only included in the service class itself? – Carven Jul 10 '16 at 07:52
  • What do u mean by if the provider is only included in the service class itself? – micronyks Jul 11 '16 at 05:47
  • I meant if there is a provider that is only used by a particular service, would it be possible for me to declare that provider only inside the file of that service? – Carven Jul 11 '16 at 05:50
  • I don't understand your point. 'Providers' is a collection of service array. In the component, you define that: I am going to use this service by putting it into providers array. Fyi, if you use providers in component,it will create different instance of the service for that component. To make service singleton, you have to inject it into bootstrap.... if you are not intented to use singleton service, you can go with providers array... – micronyks Jul 11 '16 at 05:55
  • Sorry if I wasn't clear about what I meant. I'm not sure if I've understood the providers incorrectly. What I understand is that `providers` have to be defined in the decorator before a class can injected. In my example, since `TestService` is injecting the `Http` class, why shouldn't the provider of `Http` be defined in `TestService`, but in `TestComponent`? Can I specify the `Http` provider in `TestService` because I don't think `TestComponent` is repsonsible for injections in `TestService`? – Carven Jul 12 '16 at 03:47
  • Seems like your perception is wrong. `Providers` is an array of injectable services. If you plan to use `single instance of the service`, you have to inject it into `bootstrap` function and not in any component via `providers` array, and if you plan not to use single instance of the service but want to have different instance per component then you have to inject it into respective component where you want to use it. Isn't it simple? – micronyks Jul 12 '16 at 04:59
  • @micronyks , he means, he has a service inside another service, so the service parent has no @ Component decorator to add 'provider': [ childservice]. The question is why HTTP_PROVIDERS is injected in bootstrap, and another services is inject in the @ Component, not will be easy to declare all provider in bootstrap or NgModule and then forget to declare in every @ Component ? when we know we need just one instance of Service in the whole app – stackdave Aug 21 '16 at 04:53
  • @stackdave, if you wish to have single instance, you can declare service in ngModule or in shared module. – micronyks Aug 23 '16 at 03:21