Using TypeScript classes along with functions to capture JSON data

When working with reactive forms, I encountered an issue understanding how data is mapped to form controls. Let's consider an object control with id and name properties, displayed as an input textbox where the user inputs the id. Utilizing autocomplete functionality retrieves the object data, such as:

{ id: 1234, description: "Some description" }

As this is an object and not a string, the input box displays [object Object] instead of the expected value format like 1234 - Some description. To rectify this, I assume that implementing a toString method for the object could help achieve the desired display format.

Below is a snippet of the form configuration:

this.orderForm = this.fb.group({
  customer: '',
  ....
  items: this.fb.array([ this.initItems() ])
  ...

The customer and item objects are similar in structure, whereby they both consist of id and description attributes.

export class Customer {
   id: string;
   descr: string;
   toString = () => this.id + " - " + this.descr
}

export class ItemDetail {
    id: string;
    descr: string;
    toString = () => this.id + " - " + this.descr
}

export class Order {
    id: string;
    ...
    customer: Customer;
    items: Item[]
}

export class Item {
    ...
    detail: ItemDetail
    ...
}

While loading order data into the form:

const itemsFGs = order.items.map(item => this.fb.group(item));
const itemsFA = this.fb.array(itemsFGs);
this.orderForm.setControl('items', itemsFA);

The challenge arises as the data is loaded as plain objects without being type casted to the appropriate classes, resulting in missing toString method implementations for nested objects. Consequently, the input boxes display [object Object] rather than utilizing the toString method.

A typical JSON representation of an order might resemble:

{
  id: "1",
  customer: {
    id: "1",
    name: "some customer"
  },
  items: [{
     detail: {
       id: "1",
       descr: "some item"
     }
  }]
}

The main concern shifts towards ensuring incoming JSON data is correctly captured within respective classes, allowing methods like toString to be accessible for proper display purposes.

Answer №1

It is important to keep in mind that when developing intricate object types in TypeScript, utilizing interfaces is highly recommended.

export interface Client {
   id: string;
   description: string;
}

In cases where you are uncertain about the parameters received from a service and anticipate potential undefined errors, it is advisable to declare those properties as optional using the following approach:

export interface ProductDetail {
    id: string;
    title: string;
    description?: string; //optional
}

export interface Purchase {
    id: string;
    ...
    client: Client;
    products: Product[]
}
export interface Client{
    id:string;
    name: string;
    location?: string; //optional
    birthdate?: Date;       //optional

}

This practice prevents optional parameters from being bound to the actual object if they are absent in the response. However, they will bind correctly when those properties are present in the service response.

Update 1 :

You should implement another level of nesting for better organization

 this.form = this.fb.group({
      firstName: ['', [Validators.required, Validators.minLength(3)]],
      lastName: ['', [Validators.required, Validators.minLength(3)]],
      clientGroup :this.fb.group({
               firstName: ['', [Validators.required, Validators.minLength(3)]],
               lastName: ['', [Validators.required, Validators.minLength(3)]],   
      }, {validator: Validators.required})
      ....
  });

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

Update the CSS styling of a parent div based on the active state of specific child divs

I have a class with 4 distinct columns. div class="mainContent"> <div class="left-Col-1" *ngIf="data-1"> </div> <div class="left-Col-2" *ngIf="!data-1"> ...

Issues with implementing routing children in Angular 8

Currently, I am in the process of building a website and facing some issues with implementing the admin section. Within my admin module, I have various components such as login, dashboard, products, etc. However, I am encountering an issue where the childr ...

Guide: Ensuring the validity of an object retrieved from a database with Nest.js class-validator

When activating a user, I need to ensure that certain optional data in the database is not empty by using class-validator dto. So far, my controller level validations for body, query, and all other aspects have been successful. The DTO file contains vali ...

The CORS policy has blocked access to XMLHttpRequest at 'https://saja.smjd.ir/api/Account/login' from the specified origin 'http://**'

I have successfully completed my project using Angular 9 on the frontend and asp.net core 3 on the backend, and deployed it to a server. However, I am facing an issue when trying to obtain or use a token from the server. Access to XMLHttpRequest at 'h ...

Issue with hydration in Next.js while trying to access the persisted "token" variable in Zustand and triggering a loading spinner

Below is the code snippet from _app.tsx where components/pages are wrapped in a PageWrapper component that handles displaying a loading spinner. export default function App(props: MyAppProps) { const updateJWT = useJWTStore((state) => state.setJWT); ...

How can Angular JS handle multiple validators being triggered at once?

Hey there, I'm currently working with validators in my Angular form setup. Here's a snippet of how it looks - I utilize Validators.compose to combine custom validators. The errors from these validators are then displayed on the HTML component. My ...

Overuse of memory and CPU causing performance issues in NgRx and Redux dev tools

Recently, I joined a new project that utilizes Angular and Redux. To my surprise, the Chrome DevTools for Redux were not enabled as it was commented out in the app.module.ts file. I decided to uncomment this section: StoreDevToolsModule.instrument({ n ...

How to extract data from JSON files using Angular 12

Having trouble with Angular and TypeScript. Need to fetch a GET API from Spring where the return variable is Page, but the JSON structure looks like this: "content": [ { "id": 1, "category": "TSHIRT&qu ...

The Angular program is receiving significant data from the backend, causing the numbers to be presented in a disorganized manner within an

My Angular 7 application includes a service that fetches data from a WebApi utilizing EntityFramework to retrieve information. The issue arises when numeric fields with more than 18 digits are incorrectly displayed (e.g., the number 23434343434345353453,3 ...

Using TypeScript TSX with type parameters

Is it possible to define type parameters in TypeScript TSX syntax? For instance, if I have a class Table<T>, can I use something like <Table<Person> data={...} /> ...

The function cannot accept a string as an argument, it specifically requires a Blob

Having run into a dilemma here. import React, { useState } from "react"; const PhotoUploader: React.FC = () => { const [photo, setPhoto] = useState(""); let reader = new FileReader(); reader.readAsDataURL(photo); const hand ...

Error encountered during unit testing: The function _reactRouterDom.useHistory.mockReturnValue is not a valid function

I'm having trouble writing unit tests for a React component implemented in TypeScript. I encountered an error when trying to mock some hook functions. Here is my current unit test implementation: import React from 'react'; import { useHisto ...

Quick tip: Adding a close 'X' button to an ng-bootstrap popover

As a newcomer to angular 5, I have been working on adding an 'x' button in the top right corner of a popover. Once this 'x' is clicked, the popover should be closed. Is there a way to achieve this using ng-bootstrap popover? Below is my ...

Value that is constantly changing for ngModel

Is it possible to use a function as a value for ngModel in Angular? I need to be able to set the value for my input at a later point in time, so I want to check if the function exists before updating the model. However, the following code snippet is not ...

Tips for retrieving URL parameters and using them to redirect to a different component in Angular4

I am exploring two interconnected applications where data is passed from the first application to the second application. Link to First Application When transitioning between the two applications, specific data is sent from the first to the second applic ...

Unable to retrieve a method from the model class in Angular 4

I attempted to utilize a method from the model class, but encountered an error: ERROR TypeError: act.sayHi is not a function Below is my code snippet: Model Class myModelClass.ts export interface IMymodel { name: string; addres ...

Looking to identify the type of a adorned class in Typescript?

Consider the following scenario: return function IsDefined(object: any, propertyName: string) { .... ] We then go ahead and decorate a property like this: class Test { @IsDefined() p1: String = ""; } Now, when we execute a test inside the ...

Updating the state of Formik

Currently, I'm knee-deep in a React project that requires a slew of calculations. To manage my forms, I've turned to Formik, and for extra utility functions, I've enlisted the help of lodash. Here's a peek at a snippet of my code: impor ...

The Angular Production Build is consuming approximately 1.5 gigabytes of memory, leading to an Out Of Memory error despite the large

Having trouble with Angular2 cli Project Production Build [ng build -prod] as it keeps getting stuck at 92% and gives an error message about running out of heap memory. Is there a solution to this issue? The project includes a large number of components. T ...

Transform the data prior to sending it back as an observable

I am fairly new to Angular 2 and the idea of Observables. However, what I am trying to accomplish should be quite simple for experienced experts :) Here's the situation: I have a component where I have subscribed to an observable coming from a servic ...