What is the best way to transform a class containing a map to and from a JSON string in JavaScript?

Recently encountered a challenge at work. Here is an example of a class I have:

class A {
    map1: Map<number, number> = new Map();
    map2: Map<string, string> = new Map();
    // a bunch of other data
    age: number = 0;
    ...
}

The goal is to convert this class to/from a JSON string. The reason for doing this is to create a function that can retrieve data and save it to a local text file.

1.

class A {
    map1: Map<number, number> = new Map();
    map2: Map<string, string> = new Map();
    test: number = 0;
    toMyString() {
        let context = '';
        context = '{'
            + '"map1":' + JSON.stringify([...this.map1.entries()])
            + ', "map2":' + JSON.stringify([...this.map2.entries()])
        return context;
    }
}
let a = new A();
a.map1.set(1, 1);
a.map1.set(2, 2);
a.map2.set('1', '1');
a.map2.set('2', '2');
let b = a.toMyString();
console.log('b: ', b);
let c = JSON.parse(b) as A;
console.log('c: ', c);     
c.map1 = new Map(c.map1);
c.map2 = new Map(c.map2);
console.log(c.toMyString()); // c.toMyString is not a function 
class A {
    map1: Map<number, number> = new Map();
    map2: Map<string, string> = new Map();
    test: number = 0;
    toMyString() {
        let context: string[] = [];
        context.push('{"test":' + JSON.stringify(this.test)  + '}');
        context.push(JSON.stringify([...this.map1.entries()]));
        context.push(JSON.stringify([...this.map2.entries()]));
        return JSON.stringify(context);
    }
}
let a = new A();
a.map1.set(1, 1);
a.map1.set(2, 2);
a.map2.set('1', '1');
a.map2.set('2', '2');
let b = a.toMyString();
console.log('b: ', b);
let data: string[] = JSON.parse(b);
console.log('data: ', data);
let c: A = JSON.parse(data[0]) as A;
console.log('c: ', c);
c.map1 = new Map(JSON.parse(data[1]));
c.map2 = new Map(JSON.parse(data[2]));
console.log('c: ', c.test);
console.log('c: ', c);
c.map1 = new Map(c.map1);
c.map2 = new Map(c.map2);
let e = c.toMyString()   //  c.toMyString is not a function
console.log(e);
  1. Describe all properties of A, which is quite complex due to the number of properties.

Answer №1

My preferred method in this scenario would be utilizing a static deserialization approach. When it comes to converting JSON into a class object, it's crucial to incorporate some additional handling, and in my perspective, integrating this functionality directly into the class is highly beneficial.

class Data {
    map1: Map<number, number> = new Map();
    map2: Map<string, string> = new Map();
    test: number = 0;
    toJSON() {
        let content = '';
        content = '{'
            + '"map1":' + JSON.stringify([...this.map1.entries()])
            + ', "map2":' + JSON.stringify([...this.map2.entries()])
            + ', "test":' + JSON.stringify(this.test)
            + '}';
        return content;
    }

    static fromJSON(input: string): Data {
        const obj = JSON.parse(input);
        const instance = new Data();
        instance.map1 = new Map(obj.map1);
        instance.map2 = new Map(obj.map2);
        return instance;
    }
}

const dataObj = new Data();
dataObj.map1.set(1, 1);
dataObj.map1.set(2, 2);
dataObj.map2.set('1', '1');
dataObj.map2.set('2', '2');
console.log(dataObj.toJSON());

const serializedData = dataObj.toJSON();

const newDataObj = Data.fromJSON(serializedData);
console.log(newDataObj.toJSON());

As a bonus tip, switching to using toJSON instead of toMyString will allow JSON.stringify(dataObj) to automatically utilize that function.

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

initialize input data in vue

How can I set a default value for an input in a date picker using Vue JS? I have tried setting the data but it's not showing up. When I inspect the element, I see this code: https://i.stack.imgur.com/fQDLL.png Here is my script: new Vue({ e ...

Using React to access the properties of objects within an array that has been dynamically mapped

For my initial dive into developing a React application, I am currently in the process of fetching data from a database and updating the state to store this information as an array. My main challenge lies in accessing the properties of the objects within t ...

Discovering country code details through the Geonames service API rather than relying on the HTML5 location object

My goal is to retrieve the country code of the user's current location using the Geonames Service API. However, it seems that the API only provides a two-letter country code instead of a three-letter one, which is what I require. To work around this i ...

Discover the seamless process of dynamically adjusting metadata to reflect current state values within the Next.js app directory

Exploring the app directory within Next.js version 13, I came across a change in the official documentation where they have replaced the old head method with metadata. Initially, I thought this feature was only available on page or layout components. Now, ...

Tips for accurately validating a pop-up form

I'm having difficulties with getting validation to function properly on my bootstrap modal. I have tried various examples without success. How can I properly implement validation for a bootstrap modal? This is my HTML: <div class="modal fade" i ...

Skrollr's transformation effect makes the text tremble

Using skrollr.js, I am implementing transition effects on an inner div nested inside another div. The inner div is positioned relatively. Here are my codes: HTML Structure <div class="outer"> <div class="inner-div" style="transition:transform ...

Utilize anonymous functions to reassign the button click event - JQuery

I'm dealing with a situation where I have 5 HTML buttons, each with a click event listener attached to it in the form of an anonymous function. For example: $('#button1').click(function(){ //some code }); At a certain poin ...

Observable is delivering each individual letter of the string one at a time

I am encountering an issue with the code I have which involves sending data to Firebase, waiting for a response, and then displaying the result to the user: sendRequest (data): Observable<any> { // Sending data to Firebase const key = this.d ...

Using Vue to Bring in External JavaScript Files

If I have 2 JavaScript files located in the 'resources/assets/js' directory, named 'app.js' and 'ext_app.js', what could be the issue? Within 'ext_app.js' file, there is a function defined like this: function testF ...

ES6 / JavaScript - Combining objects based on a particular key

I am attempting to merge an object based on a specific key (where 'field' serves as the key) but I am struggling to find a solution. The images below provide a visual representation of my issue. https://i.sstatic.net/FOAYo.png https://i.sstatic ...

Using create-react-app with TypeScript for server-side rendering

My current project is built with create-react-app using typescript (tsx files). I'm now interested in implementing SSR for the project, but I'm not exactly sure where to begin. In the past, I've successfully implemented SSR with typescript ...

Displaying specific choices depending on the previous selection made

I am facing an issue in Laravel where I have two selection options, and one depends on the other. Despite multiple attempts, I haven't been able to resolve it. The database structure is as follows: companies id title channels id company_id title I ...

Using AngularJS to implement validation on radio buttons

My application is a cross-platform app that utilizes AngularJS, Monaca, and Onsen UI. Within one of the views, there exists an array of list items where each item can be associated with a random number of radio buttons. These lists are dynamically generat ...

What steps can be taken to confirm the accuracy of input before sending it

Having trouble with validating input before submitting? Every time I run submit(), something seems to be going wrong :( const [value, setValue] = React.useState(""); const [error, setError] = React.useState(""); const validate = () => { value.length ...

Leveraging ng-class with multiple conditions

My goal is to assign one of three different classes to a span element based on the result of a JavaScript function. The code snippet I have written appears to be returning the correct value, but the markup always displays the 'require-matched' cl ...

Annotating Vue Computed Properties with TypeScript: A Step-by-Step Guide

My vue code looks like this: const chosenWallet = computed({ get() { return return wallet.value ? wallet.value!.name : null; }, set(newVal: WalletName) {} } An error is being thrown with the following message: TS2769: No overload ...

Adding products to an owl-carousel in an HTML document using JavaScript

When I try to add my products to an owl-carousel using JavaScript, the display is not correct. My HTML code looks like this: <div class="container mt-5 mb-5" data-aos-anchor-placement="top-center"> <div class="owl-carouse ...

When invoking a callback function that includes a conditional type, TypeScript mandates the inclusion of a parameter that intersects multiple types

There is a function that requires specific arguments, including a callback function that takes an object or an array of objects based on an isArray parameter. I am attempting to create a new feature. type Option = { name: string value: string } type ...

Unable to identify the element ID for the jQuery append operation

After attempting to dynamically append a textarea to a div using jQuery, I encountered an issue. Despite the code appearing to work fine, there seems to be a problem when trying to retrieve the width of the textarea using its id, as it returns null. This s ...

Looking through a Json file and retrieving data with the help of Javascript

I am currently working on developing a dictionary application for FirefoxOS using JavaScript. The structure of my JSON file is as follows: [ {"id":"3784","word":"Ajar","type":"adv.","descr":" Slightly turned or opened; as, the door was standing ajar.","tr ...