What is the optimal method for defining a JSON serialization format for a TypeScript class?

Currently, I am in the process of developing a program using Angular and TypeScript. Within this program, there is a specific class named Signal that consists of various properties:

export class Signal {
    id: number;
    obraId: number;
    obra: string;
    descripcion: string;
    rangoInferior: string;
    rangoSuperior: string;
    unidades: string;
    // additional properties

    // Utilizing the ofJson method to create a Signal object
    static ofJson(signalJson: ISignalJson): Signal {
        return this.createSignal(signalJson.id, signalJson.obraId, signalJson.obra, 
            signalJson.descripcion, signalJson.rangoInferior, signalJson.rangoSuperior,
            signalJson.unidades
        );
    }

    static createSignal(id: number, obraId: number, obra: string,descripcion: string, rangoInferior: string, rangoSuperior: string,
        unidades: string
    ): Signal {
        const new_signal = new Signal();
        new_signal.id = id;
        new_signal.obraId = obraId;
        new_signal.obra = obra;
        new_signal.descripcion = descripcion;
        new_signal.rangoInferior = rangoInferior;
        new_signal.rangoSuperior = rangoSuperior;
        new_signal.unidades = unidades;
        return new_signal;
    }
}

Upon receiving data from an API, certain fields (description, rangoInferior, rangoSuperior) may have a value of null which should be set to an empty string. To achieve this, private properties and getters/setters are used.

For instance:

private _descripcion: string;
public get description(): string {
    return this._descripcion;
}
public set description(value: string) {
    this._descripcion = value ? value : "";
}

The issue arises when the object is processed with JSON.stringify as it includes underscore fields which can result in errors when sent back to the API.

{
  "_description": "sampletext",
  "id": 123456,
  "obra": "TEST-PROJECT",
  "obraId": 789,
  "_rangoInferior": '',
  "_rangoSuperior": '',
  "_unidades": ''
}

Various solutions have been proposed to address this challenge:

  • Implement a toJson method to eliminate the underscores.
  • Utilize Object.defineProperties in the following manner:
    Object.defineProperties(
        this,
        {
            _description: { 
                writable: true, 
                enumerable: false 
            },
            description: {
                get() { return this._description; },
                set(value: string) { this._description = value ? value : ""; },
                enumerable: true
            }
        }
    );
    
  • In your opinion, what would be the most effective solution?
  • Are there any alternative approaches that you believe need to be taken into consideration?

Answer №1

To ensure smooth parsing from JSON using toJson(), always remember to include a reviver function when utilizing JSON.parse(). Proper documentation of this practice is crucial for maintaining clean and efficient code.

Consider opting for Object.defineProperties() as an alternative method. While more verbose, this approach offers greater control over the process. By specifying which properties are writable and enumerable, you gain additional benefits beyond just supporting JSON.stringify() and JSON.parse().

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

Is there a way to iterate over an object with predetermined keys and then utilize those keys to access another object of the same type?

What I'm attempting to do next is calculate the total value of value in pounds. However, this is causing an error message stating: TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used ...

How to fix an unresolved TypeScript import?

Within my node_modules directory, there is a package that contains the following import statement: import { x } from 'node_modules/@types/openfin/_v2/main'; Unfortunately, I am receiving an error message stating "cannot find module 'node_mo ...

Develop a user interface that includes the ability to have unspecified properties of an unspecified data type,

interface Sample { value?: string [prop: string]: any } const sampleObject: Sample = { title: 'John' } const data = sampleObject.title By including "any" in the interface, it eliminates the automatically assumed "string" type for the p ...

Using TypeORM to establish a ManyToOne relationship with UUID data type for the keys, rather than using integers

I am currently facing a challenge in my Typescript Nestjs project using TypeORM with a PostgreSQL database. The issue arises when trying to define many-to-one relationships, as TypeORM insists on creating an ID field of type integer, while I prefer using U ...

Guide to locating a particular node within an array of nested objects by utilizing the object

Dealing with an array of nested objects, the goal is to compare values with a flat array and update the property matchFound. If the parent's matchFound is true, then all its children should inherit this value. treeData = [{ field: 'make&a ...

Is there a way to modify the style within a TS-File?

I've created a service to define different colors and now I want to set separate backgrounds for my columns. However, using the <th> tag doesn't work because both columns immediately get the same color. Here's my code: color-variatio ...

How can Vue be used to dynamically change the input type on focus?

What Vue method do you recommend for changing an input element's type on focus? e.g. onfocus="this.type = 'date'" I am specifically looking to switch the input type from text to date in order to utilize the placeholder property. ...

Nextjs doesn't render the default JSX for a boolean state on the server side

I am working on a basic nextjs page to display a Post. Everything is functioning smoothly and nextjs is rendering the entire page server side for optimal SEO performance. However, I have decided to introduce an edit mode using a boolean state: const PostPa ...

Obtaining an instance of the CKEditor Editor in TypeScript with CKEditor 4: what's the best way?

Can someone explain how to utilize the CKEDITOR 4 plugin in TypeScript for an Angular 9 application? I am looking to set the configuration through TypeScript (specifically for autogrow) and also implement an INSERT HTML function. I have already imported ...

A guide to iterating over an array and displaying individual elements in Vue

In my application, there is a small form where users can add a date with multiple start and end times which are then stored in an array. This process can be repeated as many times as needed. Here is how the array structure looks: datesFinal: {meetingName: ...

No issues raised by Typescript/tslint regarding this in arrow function

After making some creative adjustments, this is what I came up with: const TopBar = () => ( <Button onPress={this.onPress} // No errors shown /> ) Although all my other rules in tslint.json are functioning properly. Is there a way to ma ...

Engage with the item provided to an Angular2 component as an Input parameter

In a nutshell, the issue stems from a missing 'this' when referencing the @Input'ed variables. Currently, I have a parent class that will eventually showcase a list of "QuestionComponents". The pertinent section of the parent class templat ...

Modify the color of the matSnackbar

I'm having trouble changing the snackbar color in Angular using Angular Material. I tried using panelClass in the ts file and adding it to the global css, but the color remains unchanged. Any suggestions on how to resolve this? I am still new to this ...

Tips for integrating Tinymce in Angular 2 once it has reached its stable version

How to Implement TinyMCE in Angular 2 with Two-Way Binding Working with Third-Party Libraries in Angular 2 After trying multiple solutions provided on stackoverflow, I am still unable to load the TinyMCE editor successfully. I am wondering if there are ...

encountering a problem integrating react-dropzone into a project using react-16.13.1

I'm having an issue adding the package https://www.npmjs.com/package/react-dropzone to my TypeScript React project using Yarn as the package manager. I ran the command yarn add @types/react-dropzone, but it ended up installing a deprecated package h ...

Encountering a type error while trying to read dummy data, as the map function is not

I am currently working on fetching dummy data from a URL in my component using TS and Next.js. Unfortunately, I encountered an error type that I am unable to diagnose. typings.d.ts: export type Themen = { id: number; title: string; description: string; ...

Avoiding data type conversion in JavaScript/TypeScript

Currently delving into the world of JavaScript, I come from a background of working with statically typed languages. Naturally, I opted to dive into TypeScript instead of starting directly with JS. While TypeScript is great and addresses many issues presen ...

Incorporate Material Design Icons into your NPM Electron React application for sleek visuals

I am currently exploring how to incorporate Material Design Icons into an NPM Electron project with Webpack 4. The Google Github page suggests that the icons can be easily installed using npm install material-design-icons. However, based on this discussion ...

Changing the order of a list in TypeScript according to a property called 'rank'

I am currently working on a function to rearrange a list based on their rank property. Let's consider the following example: (my object also contains other properties) var array=[ {id:1,rank:2}, {id:18,rank:1}, {id:53,rank:3}, {id:3,rank:5}, {id:19,r ...

Obtain the last used row in column A of an Excel sheet using Javascript Excel API by mimicking the VBA function `Range("A104857

Currently in the process of converting a few VBA macros to Office Script and stumbled upon an interesting trick: lastRow_in_t = Worksheets("in_t").Range("A1048576").End(xlUp).Row How would one begin translating this line of code into Typescript/Office Scr ...