An instance of an abstract class in DI, using Angular version 5

I have multiple components that require three services to be injected simultaneously with the same instance. After that, I need to create a new instance of my class for injecting the services repeatedly. My initial idea was to design an abstract class and inject all the services there. Then each component would extend the abstract class, but this approach did not work as expected.

Here is the abstract class:

import { Component, Injector } from '@angular/core';
import {GeomqttdataproviderService} from '../protocols/geomqtt/geomqttdataprovider.service';
import {MqttdataproviderService} from '../protocols/mqtt/mqttdataprovider.service';
import {CoapdataproviderService} from '../protocols/coap/coapdataprovider.service';


@Component({
  selector: 'app-abstract',
  templateUrl: './abstract.component.html',
  providers: [
    MqttdataproviderService, GeomqttdataproviderService, CoapdataproviderService 
  ],
  styleUrls: ['./abstract.component.css']
})
export class AbstractComponent  {


  protected GeomqttdataproviderService: GeomqttdataproviderService;
  protected MqttdataproviderService: MqttdataproviderService;
  protected CoapdataproviderService: CoapdataproviderService;

  constructor(injector: Injector) {
    this.GeomqttdataproviderService = injector.get(GeomqttdataproviderService);
    this.MqttdataproviderService = injector.get(MqttdataproviderService);
    this.CoapdataproviderService = injector.get(CoapdataproviderService);
  }


}

Sample code for one of the consuming components:

    import { Component, OnInit, Injector } from '@angular/core';
    import {AbstractComponent} from '../../abstract/abstract.component';

    @Component({
      selector: 'app-gauge',
      templateUrl: './gauge.component.html',
      styleUrls: ['./gauge.component.css'],
      providers: [
        AbstractComponent
      ],
    })
    export class GaugeComponent extends AbstractComponent  {

      temp = [];

      data = [
        {
          name: '',
          value: ''
        }
      ];
    constructor(injector: Injector) {

        super(injector);


        this.CoapdataproviderService.msg$.subscribe(() => {
          this.temp = [{name: this.CoapdataproviderService.coapform.addcoaptopicfilter, value: this.CoapdataproviderService.msg}]; 
          this.temp = this.data;
          this.data = [{name: this.CoapdataproviderService.coapform.addcoaptopicfilter, value: this.CoapdataproviderService.msg.slice(-1)[0]  }];
        });

        this.GeomqttdataproviderService.geomsg$.subscribe(() => {
          this.temp = [{name: this.GeomqttdataproviderService.geomqttform.addgeomqtttopicfilter, value: this.GeomqttdataproviderService.geomsg}];  
          this.temp = this.data;
          this.data = [{name: this.GeomqttdataproviderService.geomqttform.addgeomqtttopicfilter, value: this.GeomqttdataproviderService.geomsg.slice(-1)[0]  }];

        });

         this.MqttdataproviderService.msg$.subscribe(() => {    
          this.temp = [{name: this.MqttdataproviderService.mqttform.addmqtttopicfilter, value: this.MqttdataproviderService.msg}]; 
          this.temp = this.data;
          this.data = [{name: this.MqttdataproviderService.mqttform.addmqtttopicfilter, value: this.MqttdataproviderService.msg.slice(-1)[0]  }];
        });
    }}


I keep encountering the error that all my services are missing in the gauge-component. However, I do not want to declare them in app.module because I require a fresh instance every time the abstract class is injected into all the components.

Answer №1

Using the providers: [AbstractComponent]
syntax does not align with best practices and may not produce the expected results. This approach will generate a new instance of the AbstractComponent class for injection, which is generally not recommended.

Currently, it's important to note that decorator annotations do not support inheritance. The providers property should be copied from the AbstractComponent to the Component annotation within all child classes.

To keep your code DRY (Don't Repeat Yourself), you can export the array and use it in multiple classes where these providers are needed:

export const DATA_PROVIDERS = [
    MqttdataproviderService, GeomqttdataproviderService, CoapdataproviderService 
];

...
@Component({
  selector: 'app-abstract',
  templateUrl: './abstract.component.html',
  providers: [DATA_PROVIDERS],
  styleUrls: ['./abstract.component.css']
})
...

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

Creating an Angular 8 build that can be executed from a subdirectory

As I develop using the standard localhost:4200, I also want to understand how a build works. To achieve this, I made some modifications in the angular.json file. The alteration is as follows: "outputPath": "D:/a_root/dist", The 'a_root' represe ...

Using TypeScript to declare ambient types with imported declarations

In my TypeScript project, I have a declaration file set up like this: // myapp.d.ts declare namespace MyApp { interface MyThing { prop1: string prop2: number } } It works perfectly and I can access this namespace throughout my project without ...

Encountering incorrect month while utilizing the new Date() object

My Objective: I am looking to instantiate a new Date object. Snippet of My Code: checkDates (currentRecSec: RecommendedSection){ var currActiveFrom = new Date(currentRecSec.activeFrom.year,currentRecSec.activeFrom.month,currentRecSec.activeFrom.day ...

Encountering HttpErrorResponse when sending a Delete request in Angular

I need help troubleshooting an issue with sending a Delete request from my movie.component.ts file to delete a review. Unfortunately, I keep receiving the dreaded HttpErrorResponse error. Can anyone pinpoint where I may be making a mistake? Take a look at ...

Exploring the Applications of Directives in Multiple Modules within Angular 2

When I declare the directive in two modules, I get an error that says Type PermissionDirective is part of the declarations of 2 modules. However, when I declare it in only one module, I receive an error stating Can't bind to 'isPermission' s ...

Is it considered best practice to include try/catch blocks within the subscribe function in RxJs?

Imagine we have an Angular 2 application. There is a service method that returns data using post(), with a catch() statement to handle any errors. In the component, we are subscribing to the Observable's data: .subscribe( ()=> { ...

What could be the reason my RxJS Observable chain does not run again when new emissions are made?

Currently, I am facing a unique challenge while working with RxJS in an Angular service. The issue revolves around two observable chains designed to enhance a stream of notifications with user data. One chain functions correctly, allowing for multiple trig ...

What is the process for turning off minifying bundles when constructing an Angular application?

After developing an Angular project and implementing Server Side Rendering (SSR) using the angular-universal package, I have successfully served my project with SSR on port localhost:4000. Now, I am looking to debug it in a similar way as we do in the sour ...

Implementing Authorization keys in Angular's Swagger UI using code

I am currently in the process of integrating swagger ui into an Angular 7 application. Utilizing the npm package swagger-ui 3.37, the API documentation is structured with swagger 2.0. The integration works smoothly when authorization is not required within ...

Utilizing Pipe and Tr in Reactive Forms to Enhance Functionality

I'm facing an issue with my reactive forms when trying to write the pipe inside a tr tag. Here is the code snippet: <tr *ngFor="let row of myForm.controls.rows.controls; "let i = index" [formGroupName]="i"| paginate: { itemsPerPage: 3, currentPage ...

JavaScript Enigma: Instantiate 2 Date variables with identical values, yet they ultimately display distinct dates on the calendar

I need some help understanding something in my screenshot. Although both tmpStart and itemDate have been assigned the same numeric value, they display different calendar dates. start = 1490683782833 -> tmpStart = "Sun Mar 26 2017 16:51:55 GMT+ ...

Invoking a function within an Angular component

I am facing a problem - is there a way to invoke a function from the name.component.html file without using a button click, and without needing to go through the .ts file or service? ...

The TypeScript error reads: "An element is implicitly assigned the 'any' type because an expression of type 'any' cannot be used to index a specific type."

[Hey there!][1] Encountering this TypeScript error message: { "Element implicitly has an 'any' type because expression of type 'any' can't be used to index type '{ 0: { image: string; title: string; text: string; }; 1: { ...

Is there a way to automatically validate v-forms inside a v-data-table when the page loads?

In my data entry form, I have utilized a v-data-table with each column containing a v-form and v-text-field for direct value updates. My goal is to validate all fields upon page load to identify any incorrect data inputs. However, I am facing challenges in ...

Can you please provide a step-by-step guide for using socket.io with TypeScript and webpack, after installing it

Currently, I am experimenting with TypeScript in conjunction with node.js, socket.io, and webpack. To facilitate this setup, I have configured the webpack.config.js, tsconfig.json, and tsd.json files. Additionally, I acquired the typings file for socket.i ...

Tips for incorporating jQuery UI into Angular 6

No matter how many methods I have tried from StackOverflow, I cannot seem to get jquery-ui to work in my angular 6 component. Here's what I've attempted: I went ahead and ran npm install jquery jquery-ui to install both jquery and jquery-ui. ...

Is there a way to create a stub for the given function using sinon?

Here is my test function: const customTestLibrary = require("./test"); describe("Initial Test", function() { it("should run the test function successfully", function(done) { customTestLibrary.execute(); done(); }); }); The te ...

Utilizing Angular 2: Implementing a template-driven form to send data from a chosen element to the submitting object

Hey there! I'm fairly new to Angular 2 and have been trying to tackle this issue for a while now. I have a user object that contains another nested object, defined by the User interface: export interface UserModel{ name: string, service: Service ...

What is the best way to set up a variable in Typescript that will be assigned the value of an asynchronous request once it is completed?

As a newcomer to typescript, I encountered an issue that hadn't occurred in my previous project. It appears that declaring a variable before an API request inside a try-catch block leads to typescript errors when attempting to use this variable after ...

Disabling click events on a span tag in Angular 6: A step-by-step guide

Is there a way to disable the click event for deleting hours with the 'X' symbol based on a condition? Thank you in advance. <table navigatable class="<some_class>"> <tbody> <tr *ngFor="let item of ...