1

Hi everyone, i'm new with Angular and I am having troubles with Injectable classes.

I have an abstract class (on web.ts) which one of its protected attributes is an HttpClient object. The definition of this abstract class is as follows:

import { HttpClient } from "@angular/common/http";


export abstract class Web {
   protected baseURL: string;

   constructor(baseURL: string, protected http: HttpClient) {
      this.baseURL =  baseURL;
   }

   public abstract RetrieveData(pattern: string);
}

Then I have another class (on webA.ts) which extends the Web class:

import { Web } from './web';

export class WebA extends Web {

   constructor() {
      super("https://www.test.com");
   }

   private Search(pattern: string) {
      pattern = pattern.replace(" ", "+");
      var searchURL = this.baseURL + `/site/searchpage.jsp?st=${pattern}&id=pcat17071`;

      console.log(searchURL);

      this.http.get(searchURL).subscribe(data => {
         console.log(data);
      });
   }

   public RetrieveData(pattern: string) {
      this.Search(pattern);
   }
}

Finally, in a class of a component for my website I want to instantiate WebA as:

private webA: Web = new WebA();

It tells me that I need to pass an HttpClient object on super("https://www.test.com"); in webA.ts. To fix it, I can make the constructor for WebA like:

constructor(@Inject(HttpClient) http: HttpClient) {
      super("https://www.test.com", http);
}

But this would lead me to do private webA: Web = new WebA(this.http); forcing me to have on my component class:

import { HttpClient } from "@angular/common/http";
...
constructor(private http: HttpClient) {}

I know there must be another way to do it because in my opinion this is breaking hierarchy on my classes

TL;DR:
I need to "auto-inject" an HttpClient on an abstract class to not to need passing this object as an argument on super in the extender class.

1
  • constructor(protected http: HttpClient) {} should do the trick Commented Jan 22, 2018 at 17:52

2 Answers 2

1

"auto-inject" works only if you want the DI mechanism to create the type for you. In your case I think it is better to declare the class WebA as injectable with @Injectable and in your class, where you need it just inject WebA instance. This way the HttpClient will be passed automatically.

@Injectable()
export class WebA extends Web {

   ...

   constructor(private httpClient: HttpClient) {
      super("https://www.test.com", httpClient);
   }

   ...

}
Sign up to request clarification or add additional context in comments.

Comments

1

Either remove the constructor in WebA

export class WebA extends Web {

   //constructor() {
   //   super("https://www.test.com");
   //}

or repeat the constructor parameters and forward them with super()

export class WebA extends Web {

   constructor(baseURL: string, protected http: HttpClient) {
      super(baseURL, http);
   }

If you need a constructor in the derived class (WebA) the only way is to repeat the parameters and forward them.

Update

There is no such thin as auto-inject when you create an instance with new Xxx(). Dependency injection works only for instances that Angulars DI creates for you.

Otherwise see my answer above.

6 Comments

I think his problem is when he wants to create the instance, he doesn't want to pass httpClient manually. Hi does not inject WebA, but creates manually
@SurenSrapyan thanks for the hint. There is no dependency injection for classes created with new .... I updated my answer.
Thats what i thought to do on first, but as I said it breaks hierarchy. Is there some way to Inject HttpClient on Web abstract class? I dont have neither WebA nor Web on app.module.ts because they are not a component of my app, just auxiliary classes. Maybe I can make angular to inject HttpClient on WebA by adding it to app.module.ts??
There is no injection for abstract classes. As I mentioned there is only injection for classes Angular instantiates for you and Angular only instantiates concrete classes.
@GünterZöchbauer Yes, I see... Then, i can add webA to @NgModule on app.module.ts on declarations [] and HttpClient in providers []? If I do so it stills says me that I still need to pass http as an argument on private webA: Web = new WebA();
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.