Invoking a function on an object of a subclass that derives from an abstract class

In the realm of abstract classes, behold this one:

export abstract class BaseStepComponent {
    /** Behold thy base-step ctor */
    constructor() {

    }

    abstract getValue(): string;

}

And lo, here is a component that inherits such abstract glory:

export class SingleChoiceStepComponent extends BaseStepComponent {
    /** Verily, the single-choice-step ctor */
    constructor() {
        super();
    }
    
    @ViewChild("itemList") itemList: ElementRef;

    getValue(): string {
        return this.itemList.nativeElement.value;
    }

}

Yea, many components follow in their footsteps, each with differing logic within getValue()

Elsewhere in my world, I have this member living within a component:

stepItems: QueryList<any>;
@ViewChildren("stepItem") set stepItemsContent(content: QueryList<any>) {
    let items = content.toArray();
    if (items.length > 0) {
        this.stepItems = content;
    }
}

The "Steps" stand tall in a wizard (a form of multiple pages), their types and numbers known not to the application, but all bow to the inheritance of BaseStepComponent

When the time cometh to gather the values returned by getValue(), an obstacle doth abound as mentioned below.

let values: any[] = [];
this.stepItems.forEach(step => {
 let v = step.getValue(); //Behold! An IDE miracle, yet it fails at runtime.
  values.push({ key: step.key, value: v });
});

Alas, due to the highborn nature of BaseStepComponent, a task ariseth unattainable:

let instance = new BaseStepComponent();
instance = Object.assign(instance, step);

Thus do I find myself at an impasse. Might thee possess knowledge on how to transcend this dilemma?

Answer №1

Below is an example of how you can use a base step component along with Angular:

export abstract class BaseStepComponent {
/** Constructor for the base-step */
constructor() {}

abstract getValue(): string;
}

@Component({
 selector: "step1",
 template: `
 <h1>Step 1</h1>
 `,
 providers: [{ provide: BaseStepComponent, useExisting: Step1Component }]
})
export class Step1Component extends BaseStepComponent {
 @Input() name: string;

 getValue(): string {
  return "Step1Component";
 }
}

@Component({
 selector: "step2",
 template: `
 <h1>Step 2</h1>
 `,
 providers: [{ provide: BaseStepComponent, useExisting: Step2Component }]
})
export class Step2Component extends BaseStepComponent {
 @Input() name: string;

 getValue(): string {
  return "Step2Component";
 }
}

To implement this code:

export class AppComponent {
  name = "Angular " + VERSION.major;

  @ViewChildren(BaseStepComponent) items: QueryList<BaseStepComponent>;

  ngAfterViewInit() {
    this.items.map((step: BaseStepComponent) => {
      console.log(step.getValue());
    });
  }
}

You can find a live demo on StackBlitz.

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

Tips for sending arguments to translations

I am currently implementing vuejs 3 using TS. I have set up my translation files in TypeScript as shown below: index.ts: export default { 'example': 'example', } To use the translations, I simply do: {{ $t('example') }} N ...

Issue with Angular2 Property Change Notification

I have a directive called app.service.ts that holds the state data of the app. I'm using this directive in other components to access and modify the app state, which is functioning correctly. However, I encounter an error when I attempt to bind a pro ...

Adding a constant to a Vue component

Currently working on developing an application using Vue and TypeScript. I'm focused on refactoring some aspects, particularly moving hard-coded strings from a template to a separate constant. What has been implemented is as follows: export const va ...

tips for extracting data from C# generic collection lists using TypeScript

This is the code I wrote in my .cshtml file: @ { var myList = (List<MyViewModel>)ViewBag.MyCollection; } <input id="myListHidden" type="hidden" data-my-list="@myList" /> Next, here is the TypeScript code that retrieves the value from ab ...

What is the functionality of .map / .subscribe in Angular2?

I am facing a challenge trying to populate 3 variables (arrays) from Firebase using AngularFire2. The structure of my database looks like this: I am struggling with resolving Promises in order to map and fill those variables. Even basic queries are not r ...

Guide to reference points, current one is constantly nonexistent

As I work on hosting multiple dynamic pages, each with its own function to call at a specific time, I encounter an issue where the current ref is always null. This poses a challenge when trying to access the reference for each page. export default class Qu ...

Retrieve upcoming route details within canDeactivate guard in the updated Angular2 router

Is there a way to retrieve the upcoming route information within the "canDeactivate" guard of Angular 2's new router? ...

Inspecting an unspecified generic parameter for absence yields T & ({} | null)

Recently, I came across a perplexing issue while responding to this specific inquiry. It pertains to a scenario where a generic function's parameter is optional and its type involves the use of generics. Consider the following function structure: func ...

retrieve document data from firestore using the service

Is there a way to get real-time data from a Firestore document using a service? According to Firebase's documentation, you can achieve this by following this link: https://firebase.google.com/docs/firestore/query-data/listen?hl=es#web-modular-api I ...

Establish a public-facing link for a React component

After developing a React component that functions as a chatbot window, I am now looking for a way to make the opening button accessible across various websites and applications. My initial thought was to associate a URL with the button so that it can be ea ...

The two-way binding does not connect the property and event halves to the same target

I am trying to create a two-way binding using reactive forms in Angular. I need to exchange data between the child component and the parent component seamlessly. This is the HTML code for my child component: <input type="text" #name class=&qu ...

Importing components with local data within an ngFor in Angular TypeScript

Having recently started working with Angular2, I am facing a challenge with importing components in ngFor loops. The issue seems to arise when importing components with data in ngFor loops; it checks for values in the .ts file instead of the local variabl ...

"What is the best way to specify a type for the src attribute in a tsx file within a

<Image src= { sessionData?.user.image} alt="user" width={100} height={100} />` An issue has been encountered: There is a type error stating that 'string | null | undefined' cannot be assigned to type 'stri ...

Tips for displaying dynamic images using the combination of the base URL and file name in an *ngFor loop

I have a base URL which is http://www.example.com, and the file names are coming from an API stored in the dataSource array as shown below: [ { "bid": "2", "bnam": "ChickenChilli", "adds": "nsnnsnw, nnsnsnsn", "pdap": " ...

`When attempting to use Typescript with Electron, the error 'exports is not defined

Trying to launch my basic electron application, I utilize Typescript for development which then compiles into JavaScript. However, upon running the app, an error is encountered: ReferenceError: exports is not defined[Learn More] file:///Users/ahmet/Docume ...

Creating new Angular2 Observables - Subscribing to undefined developments

Is it a scoping issue or a problem with how my observables are set up? Can you assist me in figuring it out? To explain my logic: My goal is to first check if the data is available locally before making an http.get request for it. I want to return the loc ...

What is the reason for the failure of class binding when used with ngOnChanges?

I am new to working with Angular. I attempted to include a class if the property isMajor is true. An if statement alters the value of the isMajor property based on the generated propName in ngOnChanges. If I remove the following line propName === &apos ...

Troubleshooting problems with Angular 6 update through the command "ng update"

https://i.stack.imgur.com/LuPSs.png I am currently in the process of upgrading from Angular version 5 to 6. When using the "ng update" command, I encountered a problem that is shown in the attached screenshot. Can someone guide me on how to resolve this ...

Eliminating the dynamic element in jQuery causes disruption to the ViewContainerRef container

In my Angular 2+ application, I am dynamically creating components using the following code snippet: @ViewChild("containerNode", { read: ViewContainerRef }) cardContainer; const factory = this.ComponentFactoryResolver.resolveComponentFactory(CardComponen ...

Exploring Geographic Navigation with Angular Maps

Currently, I'm implementing Google Maps into my Angular SPA by following this helpful article. The HTML code in app.component.html looks like this: <html> <head> <meta charset="utf-8" /> <title>Map</titl ...