Error encountered during an object casting operation at runtime

I am currently tackling a project in Typescript. Even though the code compiles without errors and adheres to all theoretical principles, it fails to function correctly at Runtime.

The root cause of this issue lies in the fact that TypeScript is transpiled into JavaScript post compilation. This means there are no explicit classes or variable types (it follows dynamic typing, similar to interpreted languages).

Now, I am seeking assistance to resolve this matter. Below is an outline of the class structure:

The Base Classes

Upon receiving an API response, I cast it to a base class type

class BaseCollectionTypeResponseModel<TObject>{

    protected responseData: Array<TObject>;

    protected pagination: PaginationResponseModel;

}

The structure of PaginationResponseModel is outlined below:

class PaginationResponseModel {
    protected totalItems: number;

    protected totalPages: number;

    protected currentPage: number;

    protected itemCount: number;

}

Additionally, I have defined an interface containing a method ConvertViaAdapter(), as shown below:

interface IConvertable{
    ConvertViaAdapter();
}

A sample class implementing the interface is detailed here:

class PlatformResponseModel implements IConvertable{

    protected status: number;

    protected name: string;

    protected platformid: string;

    protected tags: string[];

    protected type: string;

    protected version: string;

    protected description: string;

    ConvertViaAdapter(): PlatformModel {
        return Object.assign(new PlatformModel(), this)
    }
}

In addition to these base classes, I'm creating child classes to leverage base class functionalities for application-specific features.

The Child Classes:

For example, the pagination child class resembles the following: class PaginationModel extends APIResponses.PaginationResponseModel{

    get TotalItems(): number{
        return this.totalItems
    }

    get TotalPages(): number{
        return this.totalPages
    }

    get CurrentPage(): number{
        return this.currentPage
    }

    get ItemCount(): number{
        return this.itemCount
    }
}

Challenges arise when extending the PlatformResponseModel with further functionality:

class PlatformFunctionalModel extends PlatformResponseModel{

    get Name(): string{
        return this.name
    }

    get IsActive(): boolean{
                if (this.type == 0)
            return True;
                return False;
    }
}

Similarly, the BaseCollectionTypeModel has been extended using Generics:

class CollectionTypeBaseModel<TObject extends YObject, YObject extends IConvertable> extends BaseCollectionTypeResponseModel<YObject>{

    private _responseData: Array<TObject> = []
    get ResponseData(): Array<TObject>{
        if (this._responseData == null || this._responseData.length < 1){
            this.responseData.forEach((data)=>{
                this._responseData.push(data.ConvertViaAdapter());
            });
        }
        return this.responseData;
    }
    set ResponseData(data: Array<TObject>){
        this.responseData = data 
        this._responseData = data 
    }

    get Pagination(): PaginationModel{
        return Object.assign(new PaginationModel(), this.pagination)   
    }
}

The issue arises in the line this.responseData.forEach() within the above class, resulting in the error:

Object type doesn't have the method ConvertViaAdapter().

According to expectations, instances of TObject should implement the ConvertViaAdapter() function when extending the IConvertable interface. However, this seems not to be the case. Assistance is requested.

Sample JSON

{"responseData":[{"status":2,"name":"HelloSample","platformid":"A1B2C3","tags":["hello","sample"],"type":"delta","version":"v1.0","description":"Just a sample"}],"pagination":{"totalItems":10,"totalPages":5,"currentPage":1,"itemCount":2}}

Starter code:

var objectData = JSON.parse(jsonData);
var myCastedData = Object.assign(new CollectionTypeBaseModel<PlatformFunctionalModel, PlatformResponseModel>(), objectData)

Answer №1

It appears that the example JSON is missing an array surrounding the responseData portion.

Given that the responseData objects seem to be regular JavaScript objects rather than instances of PlatformResponseModel, you will need to find an alternative method for passing a conversion function into CollectionTypeBaseModel. One possible approach could be passing it as a constructor parameter:

class CollectionTypeBaseModel<TObject extends YObject, YObject extends IConvertable> extends BaseCollectionTypeResponseModel<YObject>{
    constructor(private converter: (obj: TObject) => any) { super(); }

    private _responseData: Array<TObject> = []
    get ResponseData(): Array<TObject>{
        if (this._responseData == null || this._responseData.length < 1){
            this.responseData.forEach((data)=>{
                this._responseData.push(this.converter(data));
            });
        }
        return this.responseData;
    }

    // ...
}

objectData = JSON.parse(jsonData);
var myCastedData = Object.assign(
    new CollectionTypeBaseModel<PlatformFunctionalModel, PlatformResponseModel>(
        (data) => Object.assign(new PlatformModel(), data)),
    objectData)

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

Explore one of the elements within a tuple

Can we simplify mapping a tuple element in TypeScript? I'm seeking an elegant way to abstract the following task const arr: [string, string][] = [['a', 'b'], ['c', 'd'], ['e', 'f']] const f ...

Dynamic React Gallery with Interactive Image Picker

Looking to develop a new photo management application as an alternative to Google Photos, with a focus on displaying and selecting images in a user-friendly way. Currently using the react-grid-gallery library for this purpose. Here is my current implement ...

Unable to retrieve the third attribute of a Class using Angular2's toString method

Here is the code snippet I am working with: import { Component } from '@angular/core'; @Component({ selector: 'my-app', template: ` <h1>Hello {{name}}</h1> <p><strong>Email:</strong> {{email}}< ...

Is it achievable to have a Dynamic Angular Output?

With multiple parent components needing a common child component that can dynamically and automatically adapt to each case, I am faced with the challenge of generating buttons using a forEach loop with data provided by the parent component (such as name, C ...

Tips on changing the name of a property within an object using JavaScript

While this question may appear to be a duplicate, there is actually a distinction. I am attempting to provide a new key that does not contain any spaces. {order_id :"123" , order_name : "bags" , pkg_no : "00123#"} My goal is ...

I'm stuck trying to figure out all the parameters for the MapsPage component in Angular 2

Currently, I am utilizing Angular2 with Ionic2 for my mobile app development. Everything was working flawlessly until I decided to incorporate a new module for Google Maps navigation. Specifically, I am using phonegap-launch-navigator for this purpose. The ...

Tips for sending props, state, or arguments to a TypeScript React component

Hey there, total newbie here... I'm currently working on a school project and I've hit a bit of a roadblock... I'm attempting to pass some props from one component to another, but for some reason, it's not working properly. The goal ...

Angular2 - adding the authentication token to request headers

Within my Angular 2 application, I am faced with the task of authenticating every request by including a token in the header. A service has been set up to handle the creation of request headers and insertion of the token. The dilemma arises from the fact t ...

Angular 2: Firebase fails to provide a response

I am facing an issue with retrieving data from my Firebase using Angular 2 and TypeScript. While console.log() works, I am unable to return the value into a variable. My DataService looks like this: import {Injectable} from "angular2/core"; import ' ...

Tips for transforming numerous observables into a single observable that emits a single value upon completion of all source observables

When submitting a form, I need to call an API method multiple times using Angular's HttpClient. Each call adds a specific item into another entity, as our backend does not provide a batch-add method. Therefore, I have to make individual calls for each ...

Animated drop-down menu in Angular 4

I recently came across this design on web.whatsapp.com https://i.stack.imgur.com/ZnhtR.png Are there any Angular packages available to achieve a dropdown menu with the same appearance? If not, how can I create it using CSS? ...

Checking to see if a string meets the criteria of being a valid ARGB value

How do I verify that a string represents a valid ARGB value, such as #ffffffff for ARGB 255,255,255,255? Is there a way to validate this using TypeScript and C#? ...

Error encountered while attempting to globally install TypeScript using npm: "npm ERR! code -13"

Issue with npm error 13 Having trouble installing typescript-g package Error details: - errno: -13, - npm ERR! code: 'EACCES', - npm ERR! syscall: 'symlink', - npm ERR! path: '../lib/node_modules/typescript/bin/tsc', ...

Is there a way to access a function or variable from within the scope of $(document)?

Whenever I attempt to utilize this.calculatePrice, it does not work and I am unable to access the external variable minTraveller from within the function. numberSpin(min: number, max: number) { $(document).on('click', '.number-spinner b ...

There seems to be an issue with compiling Typescript on a particular machine

My small project compiles perfectly on my home machine, but I encounter hundreds of errors when trying to compile it on another PC. The only noticeable difference in the environment is that the problematic PC is running Windows 8 (machines running Windows ...

In Angular 5, when you reset a required form control in a reactive form, the required error message beneath the input field is not cleared

Within my template, there is a form that becomes visible when a button is clicked- <form [formGroup]="person" (ngSubmit)="onSubmitNewPerson()" #formDirective="ngForm"> <mat-form-field> < ...

Having trouble with Angular router.navigate not functioning properly with route guard while already being on a component?

I am currently troubleshooting an issue with the router.navigate(['']) code that is not redirecting the user to the login component as expected. Instead of navigating to the login component, I find myself stuck on the home component. Upon adding ...

Adding dynamic CSS to a Typescript component in Angular 5 is a powerful way to

I have a unique challenge at hand. I am currently utilizing AngularTS with C# on the server-side and TypeScript on the client-side. I am looking to enhance our application by allowing customers to input CSS styles in a text box or specify file locations ( ...

Having trouble utilizing the DatePicker component in my react native application

I've encountered an issue while using DatePicker in react native. Whenever I try to use it, an error pops up saying: "render error a date or time must be specified as value prop". Here is the link to my repository: my github repository const [date, se ...

How to Implement a ForwardedRef in Material-UI using Typescript

Currently, I have implemented a customized checkbox that is being forwarded as a component to a DataGrid. const CustomCheckbox = ({ checkboxRef, ...props }: { checkboxRef: React.ForwardedRef<unknown>; }) => ( <Checkbox {...props} ...