k11k2
k11k2

Reputation: 2044

abstract class constructor throws error

I have an abstract class where I mentioned all my http calls and while extending it in child services throws error on compile time.

Can't resolve all parameters for MyService : (?).

baseservice.ts

import { HttpClient, HttpHeaders } from '@angular/common/http';

export abstract class BaseService{

    constructor(private http: HttpClient){} //http undefined on compile time                            

    get(){
       return this.http.get()
    }    
}

myservice.ts

@Injectable()
export class MyService extends BaseService{

  getSource() {
    return this.get('api/Source')
  }
}

If I added other injectTokens in constructor of abstract class this leads to not defined error

constructor(private http: HttpClient, @Inject(APP_CONFIG) private appConfig: any | undefined) {}

Uncaught ReferenceError: http_1 is not defined

if I trying to add Options, it initialising the HttpClient and all working fine

HttpOptions = {
   headers: new HttpHeaders({
    'Authorization': `Bearer ${this.token}`
   })

What is the reason behind this and how to over come this issue while creating instance HttpClient without any InjectTokens or httpOtions.

Upvotes: 0

Views: 1590

Answers (2)

Estus Flask
Estus Flask

Reputation: 222493

http: HttpClient metadata should be emitted at compilation time on order to be recognized as dependency injection. Due to how emitting of type metadata works, a decorator should be specified on a class that contains metadata.

In a hierarchy of injectable classes that have dependencies annotated with TypeScript types like http: HttpClient, base class needs @Injectable() decorator:

@Injectable()
export abstract class BaseService{
    constructor(private http: HttpClient) {}                       
}

export class MyService extends BaseService {}

If child class has its own constructor, it needs @Injectable() decorator, too:

@Injectable()
export abstract class BaseService{
    constructor(private http: HttpClient) {}                       
}

@Injectable()
export class MyService extends BaseService {
    constructor(http: HttpClient, private foo: Foo) {
        super(http);
    }                       
}

Because of how @Injectable works, it isn't necessary in classes that use explicit @Inject annotation.

Upvotes: 0

Alan Grosz
Alan Grosz

Reputation: 1325

Your abstract class has a constructor, so...you have to declare the constructor too in the concrete class, and invoke to super:

@Injectable()
export class MyService extends BaseService{

  constructor(private http: HttpClient){
    super(http);
  }

  getSource() {
    return this.get('api/Source')
  }
}

Upvotes: 2

Related Questions