Injecting a service into a parent class in Angular 6 without the need to pass it through the constructor

Can anyone provide guidance on how to incorporate a service with multiple dependencies into an abstract class that will be inherited by several classes, in a more streamlined manner than passing it through all constructors?

I attempted to utilize static methods, but encountered the issue where the singleton instance variable would not be initialized if the service was never instantiated elsewhere.

Illustrated below is a simplified example:

@Injectable({
  providedIn: 'root'
})
export class AnimalService {

  constructor(private http: HttpClient, private userService: UserService) {}

  countTotalInDB(type): number {
    return this.http.get(...);
  }

  getUserAnimals(userId: number) {
    return this.userService.getUser(userId).animals;
  }

}

abstract class Animal {

  constructor() {}

  public getTotalInDataBase(type): number {
    // How can we access an instance of AnimalService here?
    return animalService.countTotalInDB(type);
  }

}

export class Cat extends Animal {

  constructor() {
    super();
  }

  public getTotalInDataBase(): number {
    return super.getTotalInDataBase('cat');
  }

}

export class Dog extends Animal {

  constructor() {
    super();
  }

  public getTotalInDataBase(): number {
    return super.getTotalInDataBase('dog');
  }

}

const doggo = new Dog();

console.log(doggo.getTotalInDataBase());

In the scenario presented above, AnimalService relies on HttpClient and UserService.

UserService may further depend on additional services.

So how can I achieve class instantiation similar to const doggo = new Dog();, which handles the creation/use/injection of AnimalService without explicit declaration in every class?

Answer №1

I've finally cracked the code on how to achieve this.

Here's a step-by-step guide based on my own experience:

import { inject } from '@angular/core'; // Answer

@Injectable({
  providedIn: 'root'
})
export class AnimalService {

  constructor(private http: HttpClient, private userService: UserService) {}

  countTotalInDB(type): number {
    return this.http.get(...);
  }

  getUserAnimals(userId: number) {
    return this.userService.getUser(userId).animals;
  }

}

abstract class Animal {

  protected animalService: AnimalService; // Answer

  constructor() {
    this.animalService = inject(AnimalService); // Answer
  }

  public getTotalInDataBase(type): number {
    // How to get a instance of AnimalService ?
    return this.animalService.countTotalInDB(type);
  }

}

export class Cat extends Animal {

  constructor() {
    super();
  }

  public getTotalInDataBase(): number {
    return super.getTotalInDataBase('cat');
  }

}

export class Dog extends Animal {

  constructor() {
    super();
  }

  public getTotalInDataBase(): number {
    return super.getTotalInDataBase('dog');
  }

}

const doggo = new Dog();

console.log(doggo.getTotalInDataBase());

This solution worked for me, so I hope it can assist you in your endeavors too!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Experiencing problems with React createContext in Typescript?

I've encountered a strange issue with React Context and Typescript that I can't seem to figure out. Check out the working example here In the provided example, everything seems to be working as intended with managing state using the useContext ...

The `setState` function is failing to change the current value

I'm having an issue with setting State in the dropdown component of semantic-ui-react while using TypeScript in my code. The selected category value is always returning an empty string "". Any suggestions on how to resolve this problem? impo ...

Keying objects based on the values of an array

Given the array: const arr = ['foo', 'bar', 'bax']; I am looking to create an object using the array entries: const obj = { foo: true, bar: true, bax: false, fax: true, // TypeScript should display an error here becau ...

Why is it necessary for me to manually include and configure all d3.js dependencies in the SystemJS config file?

Currently, I am utilizing the systemjs.config.js file for an Application built on Angular5.x. To implement DAG charts in the application, I installed npm install --save @swimlane/ngx-graph and npm install --save @swimlane/ngx-charts. I have set up a comp ...

Exciting updates revealed upon new additions (angular)

I'm working with three components in my Angular application: app.component, post-create.component, and post-list.component. Let's take a look at the structure of these components: <app-header></app-header> <main> <app-post-c ...

Is it possible to perform a HTTP POST request using Angular by opening a new window?

I'm facing some challenges while trying to make an HTTP post request in my angular app from the right-sidebar component. Whenever a user clicks on a button, this function is triggered: //right-sidenav.component.html info() { this.infoService.getI ...

"Encountered a runtime error while trying to execute the doubleClick() function using Pro

Encountering the following issue: "WebDriverError: Unable to convert: Error 404: Not found" while running a test with protractor: browser.actions().doubleClick(elem).perform(); or browser.actions().click(elem).click(elem).perform(); Uncertain of t ...

When the value remains unchanged, Angular's @Input() value does not get updated

Upon running this program, I initially receive the output as false, 5, 500 since they have been initialized in the child component. However, upon clicking the update button, I am unable to revert to the previous values. Instead of getting true, 10, 1000, I ...

Transferring Information in Angular 8 between components on the Same Level

Currently utilizing Angular 8 with two independent components. One component contains a form with an ID field, and the other is accessed by clicking a button from the first component. The second component does not display simultaneously with the first. A ...

The RxJs 'from' function is currently producing an Observable that is unrecognized

import { Tenant } from './tenant'; import { from, Observable } from 'rxjs'; export const testTenants: Tenant[] = [ { 'tenant_id': 'ID1' } ] const tenants$: Observable<Tenant>= from(testTenant ...

Facing issue with local redis session not functioning as intended

I'm encountering an issue with my redis session not functioning properly when testing locally. EDIT: Additionally, I realized that it's failing to save a cookie when trying to set req.session[somekey] as undefined like so: req.session.user = u ...

Replacing URLs in Typescript using Ionic 3 and Angular

Currently facing some difficulties getting this simple task to work... Here is the URL format I am dealing with: https://website.com/image{width}x{height}.jpg My objective is to replace the {width} and {height} placeholders. I attempted using this func ...

Is there a way for Ionic to remember the last page for a few seconds before session expiry?

I have set the token for my application to expire after 30 minutes, and I have configured the 401/403 error handling as follows: // Handling 401 or 403 error async unauthorisedError() { const alert = await this.alertController.create({ header: 'Ses ...

Unable to remove item from store using NgRx is causing issues

I recently started learning NgRx and decided to build a small app for practice. The app consists of two text fields where users can add items to a list, which is then displayed on the screen. While I successfully managed to add items to the list, I encount ...

Unexpected alteration of property value when using methods like Array.from() or insertAdjacentElement

I'm encountering an issue where a property of my class undergoes an unintended transformation. import { Draggable, DragTarget } from '../Models/eventlisteners'; import { HeroValues } from '../Models/responseModels'; import { Uti ...

Unveiling the Mysteries of HTTP Headers in Angular

Seeking a way to retrieve a token set in the http header within my Angular application. This is how my Angular application is being served: var express = require('express'); var app = express(); var port = process.env.PORT || 3000; var router = ...

What is the reason for the lack of overlap between types in an enum?

I'm having trouble understanding why TypeScript is indicating that my condition will always be false. This is because there is no type overlap between Action.UP | Action.DOWN and Action.LEFT in this specific scenario. You can view the code snippet and ...

`Is there a way to display a server-side file (image) in Angular using rendering techniques?`

After successfully saving a file in the database using my Java server, I am now faced with the challenge of displaying that file on my Angular side. The file is of MIME type image/jpg. When attempting to send a GET request, I can retrieve the image correc ...

The class function in the exported typescript logs that "this" is not defined

I am currently facing an issue with my TypeScript class where I am setting class values in a constructor and referencing them using "this" in a class method. While the .ts file compiles without any warnings, when I import the compiled .js file into another ...

troubleshooting angular universal with HTTPS

My angular universal app is all set up and running smoothly for POST requests on the server-side using localhost to pre-render my app. An example of a working URL would be http://localhost:8000/api/get-info. However, things took a turn when I deployed the ...