Methods for transforming a TypeScript class instance containing getter/setter properties into a JSON format for storage within a MySQL database

I am currently working on a TypeScript class that includes a getter and setter method:

export class KitSection {

    uid: string;
    order: number;

    set layout(layout: KitLayout) {
        this._layout = new KitLayout(layout);
    }

    get layout() {
        return this._layout;
    }

    private _layout: KitLayout;

    constructor(init?: Partial<KitSection>) {
        Object.assign(this, init);
    }

}

// An instance can be created like this:
const section = new KitSection(data);

The task at hand is to send this instance as a JSON object with a POST request to the server for storage in a MySQL database column of type JSON. The initial approach was to use:

const jsonSection = JSON.parse(JSON.stringify(section))

Although this successfully creates a JSON object, upon inspection in the console, the private getter/setter variable is displayed instead of the public variable within the object:

console.log(jsonSection);

///IN CONSOLE///

uid: "a"
order: 0
_layout: {_rows: Array(2), columns: 12}

To avoid storing the private variable _layout in the database, it is essential to store its public counterpart defined in the getter/setter as layout.

An alternative solution from this answer proposes adding a method to convert to JSON:

public toJSON(): string {
    let obj = Object.assign(this);
    let keys = Object.keys(this.constructor.prototype);
    obj.toJSON = undefined;
    return JSON.stringify(obj, keys);
}

However, this implementation results in an empty object. Upon investigation by logging this.constructor.prototype, all properties are visible but appear greyed out, leading to an empty array when used with Object.keys(). The question remains - why are these constructor properties greyed out?

Answer №1

JSON.stringify works by iterating only over the own enumerable properties of an object. In this case, if a property like layout is part of the prototype object rather than the instance itself, the getter associated with it will not be invoked when stringifying the instance. However, if the property _layout is an own enumerable property, it will be included in the result.

An example illustrating this behavior is where the resulting stringified object appears empty:

const obj = Object.create({
  get prop() {
    return 'val';
}
});
console.log(JSON.stringify(obj));

A possible solution to address this issue is by placing the getter directly on the instance and by ensuring that the _layout property is non-enumerable. This modification ensures that the getter will be invoked during stringification, while preventing the inclusion of _layout:

export class KitSection {

uid: string;
order: number;

private _layout: KitLayout;

constructor(init?: Partial<KitSection>) {
Object.defineProperty(
this,
'layout',
{
enumerable: true,
get() {
return this._layout;
},
set(newVal) {
this._layout = new KitLayout(newVal);
}
}
);
Object.defineProperty(
this,
'_layout',
{
enumerable: false,
value: undefined,
}
);
Object.assign(this, init);
}
}

const section = new KitSection(data);

For improved readability, using private class fields syntax provides a neater representation:

export class KitSection {
#layout: KitLayout | undefined;
constructor(init?: Partial<KitSection>) {
Object.defineProperty(
this,
'layout',
{
enumerable: true,
get() {
return this.#layout;
},
set: (newVal) => {
this.#layout = new KitLayout(newVal);
}
}
);
Object.assign(this, init);
}
}

Additionally, you can manually invoke the getter method if required.

If the serialization of KitLayout is essential, for reinstating the serialized object as a KitSection instance, either the constructor or a helper method within KitLayout should facilitate the transformation. By passing the serialized data through the constructor again or a specific method like integrateLayout, the private property can be properly set up:

integrateLayout(layoutInfo) {
this.#layout = KitLayout.makeKitLayoutFromLayoutInfo(layoutInfo)
}

In this scenario, layoutInfo refers to the plain object containing the serialized data.

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

Remove an item from a complex JSON structure based on the specified name. The function will then return the

Hey there, I'm just starting out with react native and I have an array of objects. My goal is to remove an inner object from this JSON data. [ { Key: 1, exchnageArr: [ { name: ”FX” }, { name: ”MK” ...

Clicking on a button in the Shield UI Grid Toolbar will apply filters to

Currently, I am working with a grid that utilizes a template for the toolbar. In this grid, there is a column labeled "Status." My goal is to filter the rows so that only those where the Status equals Request to Reschedule, Cancelled, Office Call Required, ...

Implement a concealed identification field with React-Admin within a React Native application

I'm currently working on incorporating the SimpleFormIterator from the React-Admin module in order to generate a list of child records within a parent record edit form. After setting up the SimpleFormIterator component with all the necessary details ...

Angular: Issue with object instantiation - Unable to assign property

Having trouble populating my array due to instantiation issues. Defined Models: user: User = { firstName: "", lastName: "", address: "" } order: Order = { OrderId: "", User: this.user, TotalPrice: 0, OrderItems: [] } Attempting to populat ...

Error encountered: "The requested resource does not have the 'Access-Control-Allow-Origin' header in Angular 6 and Nodejs."

I have encountered an issue with my Angular 6 app and Node.js. When I submit the form, I am receiving the following error: Failed to load http://localhost:3000/contact/send: Response to preflight request doesn't pass access control check: No 'Ac ...

What is the best way to pass an array to a JavaScript function from a different page?

My website has a static settings page where my JavaScript function uses AJAX to retrieve data from a MySQL table and display it in a table on an HTML document. It's working perfectly, gathering all the necessary data efficiently. Here's the code ...

Trouble with top attribute functionality within animate function

Why does the top attribute in the animate function of JQuery not seem to work, while the opacity attribute functions correctly in the code snippet below? $(function() { $(window).on('scroll', function() { ...

Encountering an issue when attempting to establish a connection to Redis using a cache manager within a Nest

Incorporating the NestJS framework into my project and utilizing Cash Manager to connect with Redis cache. Successfully connected with Redis, however encountering an error when attempting to use methods like set/get which shows 'set is not a function& ...

The process of selecting particular words from a data-attribute value

Is it possible to extract specific words from a data attribute in a web application while preserving spaces? I am looking to: Select the first word Select the last word Select the word that precedes... Select the word that follows... Select everything t ...

Creating custom functions within views using Sencha Touch 2

I'm having trouble creating my own function in Sencha Touch 2 and I keep receiving an error: Uncaught ReferenceError: function22 is not defined The issue seems to be coming from my Position.js file located in the View directory. Ext.define(' ...

Guide to manipulating DOM elements with Angular.js: inserting or deleting elements using createElement

Within my Angular directive, I am dynamically generating an external script from the DOM for a specific object within a list. This script includes both a 'script' tag and div content. While I am able to successfully add the script, I am encounter ...

Is there a way to create multiple POJOs from a JSON string?

Here is the JSON data I'm working with: {"event_type": "[new,update,delete,close]","event_payload": [{"comment_id": 123,"comment_text": "","comment_type": "DIDWELL"}],"event_retrospective_id": 500,"event_error": ""} The Pojo class that was generate ...

Error encountered when processing a PUT request for a node causing a

After receiving minimal views and replies on a similar question I posted last night, I am reaching out again in hopes of resolving my issue. For the past two days, I have been struggling to fix this problem and progress with my project! If you are interes ...

What is the best way to iterate over an indexed attribute in PHP?

Here is my ajax code snippet: $.ajax({ type: "POST", url: "bee_sesi_edit.php", data: 'serv_ruang='+ serv_ruangx +'&who='+names +'&sesi_d1='+ sesi_d1 +&apos ...

When comparing org.json.simple.JSONObject and org.json.JSONObject, the issue of JSONException not being able to be resolved as a

Could someone clarify the distinctions between org.json.simple.JSONObject and org.json.JSONObject? Also, I am encountering an issue with a code that uses org.json.JSONObject and org.json.JSONException. While editing the code in Eclipse (JUNO), it recogniz ...

What could be causing the issue with the functionality of third-level nested SortableJS drag-and-drop?

I am currently utilizing SortableJS to develop a drag-and-drop form builder that consists of three types/levels of draggable items: Sections, Questions, and Options. Sections can be dragged and reorganized amongst each other, Questions can be moved within ...

Attempting to call a Struts 2 action class from AngularJS using an HTTP GET request, however, no response is being received

I have been working on a simple application that involves making a call to Struts 2 through AngularJS. The process includes sending an HTTP GET request from AngularJS to fetch JSON data from the server. On the server side, I have created an action class na ...

Struggling to fetch information from API through Express in NodeJS with MongoDB, currently loading

I am in the process of creating a Rest API using Node.js, Express, and MongoDB. Currently, I am running it on my local host:3000. When I attempt to restart and run the server, I utilize the route http://localhost:3000/drinks To send HTTP requests, I use P ...

Send a request for a multidimensional array to a PHP file using AJAX

I am in need of an array containing subarrays. Within my ProcessWire page, there are pages and subpages with various fields. I have organized this information into an array of arrays as shown below. <?php $allarticles = $pages->find("template=a ...

Troubleshooting a 404 error for an existing object: What to do?

I encounter a 404 'Not Found' error when attempting to edit a mark through my form. I am puzzled by the source of this error because in order to access this form, I require the brand ID (which can be found in the URL). Upon accessing my modifica ...