3

I have three classes:

@Injectable()
export class ApiService {
  constructor(public http: Http) {}

  get(url: string) {
    return http.get(url);
  }

}

@Injectable()
export abstract class BaseService {
  constructor(protected serv: ApiService) {}  
}

@Injectable()
export class MediaService extends BaseService {

  // Why do we need this?
  constructor(s: ApiService) {
    super(s)
  }

  makeCall() {
    this.serv.get("http://www.example.com/get_data")
  }

}

In Angular2 I have to include for both the constructor of BaseService and MediaService even though MediaService inherits the BaseService.

How can I get Angular2 injection into the BaseService without having it in the constructor of MediaService?

Now I have all the classes extending the BaseService depending on the ApiService while they inherit from the BaseService.

SnareChops
  • 13,175
  • 9
  • 69
  • 91
Bas van Dijk
  • 9,933
  • 10
  • 55
  • 91

2 Answers2

1

If you want to get it passed in by DI you have to use the constructor. Constructors are not inherited therefore you need to implement the constructor in each and every subclass and pass arguments to the superclass constructor by calling super(arguments). The only exception are default constructors without any arguments which are kinda autogenerated.

What you could do is to inject Injector and pass it forward to the superclass where the superclass requests Http from the Injector imperatively. This might be a bit of an advantage if you inject multiple services because you only have to declare one constructor argument but in my opinion this makes it harder to reason about the code.

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • 1
    seems your answer is useful it would be better if you provide some example or elaborate your answer more. thanx ! – Pardeep Jain Feb 04 '16 at 17:50
  • Do you have an example where you use this pattern? – Bas van Dijk Feb 04 '16 at 21:52
  • Service classes that extend other services? Not yet, but I expect to run into situations where I will use it. Injecting the Injector? I experimented with it to work around Angular limitations, but otherwise I try to avoid it. – Günter Zöchbauer Feb 05 '16 at 04:19
  • I just found http://willseitz-code.blogspot.com.au/2015/08/angular-and-typescript-inheritance-and.html?showComment=1454628375575 who came to the same conclusion a while ago. – Günter Zöchbauer Feb 05 '16 at 11:22
1

I think that it's not something supported. It's the way dependency injection works in Angular2, i.e. based on decorators. The latters uses the constructor of the associated class to determine what must be injected. You must be aware that the concept of class and extends are natively supported by TypeScript but such code is transpiled into JavaScript.

See this answer for more details about the transpiled code:

Hope it helps you, Thierry

Community
  • 1
  • 1
Thierry Templier
  • 198,364
  • 44
  • 396
  • 360
  • Thanks. If this is the case, is there a way to have a globally accessible service which is not needed to inject in every constructor? – Bas van Dijk Feb 04 '16 at 17:08