My instance transforms with the arrival of a JSON file

I'm grappling with a query about data types in TypeScript and Angular 2. I defined a class in TypeScript

export class product{
    public id:number;
    public name:string;
    public status:boolean;
    constructor(){}
}

and I initialize an instance of this class for system use.

private product:Product = new Product();

When I'm utilizing this product instance within TypeScript, it retains its product type. However, the issue arises when my backend is in PHP/Laravel. The backend sends me a JSON object when retrieving a product from the server, which I then assign to my product instance.

this.productService.getProductById(id).subscribe(result => {
      this.product = result;
});

Upon assignment, the instance transitions from a product type to an object type. This realization dawns on me as I conduct console.log checks before and after the reassignment.

this.productService.getProductById(id).subscribe(result => {
       console.log(this.product);   
       this.product = result;
       console.log(this.product); 
});

Console output:

Imagens {}
Object {id: 1, namme: "test", status: true…}

This presents an issue as I aim for strict data typing. Additionally, if the server response introduces a property not originally defined in the class, it gets added to the product instance. I seek a solution to ensure that my class instance only contains the predefined attributes.

Does anyone have insights on resolving this query?

Answer №1

Setting Up

Assigning the result to this.product does not properly establish the prototype for result. To ensure that result is of type Product, it is suggested to include a constructor in the Product class that takes a data object and initialize this.product as shown below:</p>

<pre><code>this.product = new Product(result);

For simpler classes, manually writing the constructor with field assignments could be sufficient:

public class Product {
    foo: int;
    constructor(obj) {
        this.foo = obj.foo;
    }
}

While this method works, it may involve duplicating each field assignment. Alternatively, a custom assign function can be used as shown below:

constructor(obj) {
    assign(this, obj, {}, {})
}

This custom assign function mimics Object.assign behavior to simplify the task and includes additional parameters for instantiating new objects within the product.

Answer №2

My approach would be as follows:

  1. Create an interface that matches the data received from the server:

    interface IItem {
        code: number;
        label: string;
        active: boolean;
    }
    
  2. Implement a constructor in the Item class to accept this interface:

    class Item {
        public code: number;
        public label: string;
        public active: boolean;
        constructor(data?: IItem) {
            if (data != null) {
                this.code = data.code;
                this.label = data.label;
                this.active = data.active;
            }
        }
    }
    

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

"I am facing issues with Nodejs $lookup as it is not producing the

I am looking to merge two document collections. The first collection, "prefix," contains an array of category IDs under the categoryId key, while the second collection, "categories," holds objects with a unique _id field. Here is my sample database structu ...

Is there a way to bring in data from a .d.ts file into a .js file that shares its name?

I am in the process of writing JavaScript code and I want to ensure type safety using TypeScript with JSDoc. Since it's more convenient to define types in TypeScript, my intention was to place the type definitions in a .d.ts file alongside my .js fil ...

Why does mapping only give me the last item when I try to map onto an object?

Why does mapping onto an object only give me the last item? Below is the object displayed in the console: 0: {Transport: 2} 1: {Implementation: 9} 2: {Management: 3} When I use ngFor, it only provides the last item const obj = this.assigned_group; // r ...

Tips on preventing the copying of .txt and .xml files with the fs-extra.copySync function

Currently, I am working on a small TypeScript assignment and facing an issue that I can't seem to solve. Any guidance or advice on the problem mentioned below would be greatly appreciated. The task at hand involves copying a directory from one locati ...

Using [(ngModel)] in Angular does not capture changes made to input values by JavaScript

I have developed a custom input called formControl, which requires me to fetch and set its value using [(ngModel)]: import { Component, Injector, OnInit, forwardRef } from '@angular/core'; import { ControlValueAccessor, FormControl, NG_VALUE_ACCE ...

Exploring the data connections in Firebase Realtime Database using angularfire2

I am in need of querying comments and only requesting users that are listed in the comment by their userId. This is the structure of my database in Firebase realtime db: { "comments" : { "c_id1" : { "commentId" : "c_id1", "commentText" ...

Tips for refreshing the current page in Angular without being redirected to the login page

Exploring an Angular example for login and registration here on stackblitz Encountering an issue where after refreshing the page, the authguard redirects me to the login page even though I am already logged in. Looking for a solution to redirect to the c ...

Vue: Defining typed props interface including optional properties

I created a method that I want to be accessible on all my Vue instances, so I can use it in case of an error and display a specific error component. Similar to the functionality provided by vue-error-page. Since I am working with typescript, I now want to ...

Vercel: Failed to create symbolic link, permission denied

I have my personal repository available at https://github.com/Shrinivassab/Portfolio. I am currently working on developing a portfolio website. However, when I attempt to execute the vercel build command, I encounter the following error: Traced Next.js ser ...

Sorting through an array of objects using a filter method

While following a tutorial, I decided to make some changes to the TypeScript for learning purposes. However, I encountered a problem when trying to create a filter function from a React context script. I have successfully implemented a function called get ...

Issue with PrimeReact dropdown component not recognizing an array in TypeScript

Trying to incorporate the PrimeReact Dropdown component in a NextJs app with TypeScript. Encountering an error when attempting to select options from the dropdown list: "Objects are not valid as a React child (found: object with keys {name, code})" The b ...

Is it possible to customize the color of the placeholder and clear-icon in the ion-search bar without affecting

I am working with two ion-search bars and I need to customize the placeholder and clear icon color for just one of them. <ion-searchbar class="search-bar" placeholder="search"></ion-searchbar> My goal is to target a specific i ...

Tips for enabling TypeScript's static typings to function during runtime

function multiply(num: number): number { console.log(num * 10) // NaN return num * 10 } multiply("not-a-number") // result == NaN When attempting to call the function above with a hardcoded invalid argument type, TypeScript correctly identifies and w ...

Is there a way to dynamically change the options in a dropdown menu using Angular?

I am facing an issue where the values in my dropdown list are changing to null when I click on the form. The add function is working correctly, but this update problem is bothering me. Can anyone provide assistance? Below is the snippet of my HTML code: ...

Can a generic type be utilized to instantiate an object?

In my code, I have a class named Entity as shown below: class Entity { constructor(readonly someValue: string) {} someFunction() {} } Now, I am trying to create a class that will handle these entities and be able to create instances of them. In or ...

The type '{ }' does not include the properties 'params', 'isExact', 'path', 'url' from the 'match<Identifiable>' type

Currently, I am utilizing react router and typescript in order to extract the id variable from a route for use in a component. However, typescript is raising an issue: The type '{}' lacks the following properties found in type 'match' ...

Ensure all fields in an interface are nullable when using TypeScript

Is it possible to create type constraints in TypeScript that ensure all fields in an interface have a type of null? For example, if I want to write a validation function that replaces all false values with null, how can I achieve this? interface y { ...

Choosing and unchoosing columns in an Angular Material table

Feel free to check out this link for more information: Angular PrimeNG Table Order Resize Toggle. It provides guidance on how to select and deselect columns in Angular Mat table. ...

The click event triggered by the onclick clone/function may not always activate the click handler

As a newcomer in the JavaScript domain, I am encountering an issue where the first clone created after clicking 'add more' does not trigger my click me function. However, every subsequent clone works perfectly fine with it. What could be causing ...

What is the best way to attach events to buttons using typescript?

Where should I attach events to buttons, input fields, etc.? I want to keep as much JS/jQuery separate from my view as possible. Currently, this is how I approach it: In my view: @Scripts.Render("~/Scripts/Application/Currency/CurrencyExchangeRateCreate ...