Converting a nested JSON object into a specific structure using TypeScript

In the process of developing a React app with TypeScript, I encountered a challenging task involving formatting a complex nested JSON object into a specific structure.

const data = {
    "aaa": {
        "aa": {
            "xxx": {
                "xxxx": {}
            }
        },
        "ab": {
            "xxx": {},
            "xxxx": {
                "xxxx": {}
            },
            "yyy": {
                "yyyy": {},
                "zzzz": {},
                "kkkk": {}
            }
        }
    },
    "bbb": {
        "": {}
    }
}

To tackle this issue, I crafted the following code snippet.

function formatData(obj: any, level: number) {
        let formattedData = '';
        if (level === 0)
            formattedData += '[';
        for (let key in obj) {
            if (typeof obj[key] === 'object') {
                formattedData += '{"value":' + level + ',';
                formattedData += '"label":"' + key + '",';
                formattedData += '"children":[' + formatData(obj[key], level + 1) + '],';
            } else {
                formattedData += '"value":' + level + ',"label":' + key + '"children":{' + obj[key] + '}}]';
            }
        }
        return formattedData;
    }

Afterwards, I intended to parse this output using Json.parse(). However, I faced difficulties with proper formatting as the curly braces were not closed correctly and it raised an error regarding 'duplicate keys.' Can anyone provide assistance in resolving these issues?

[
  {
    "value": "aaa",
    "label": "aaa",
    "children": [
      {
        "value": "aa",
        "label": "aa",
        "children": [
          {
            "value": "xxx",
            "label": "xxx",
            "children": [
              {
                "value": "xxxx",
                "label": "xxxx"
              }
            ]
          }
        ]
      },
      {
        "value": "ab",
        "label": "ab",
        "children": [
          {
            "value": "xxx",
            "label": "xxx"
          },
          {
            "value": "xxxx",
            "label": "xxxx",
            "children": [
              {
                "value": "xxxx",
                "label": "xxxx"
              }
            ]
          },
          {
            "value": "yyy",
            "label": "yyy",
            "children": [
              {
                "value": "yyyy",
                "label": "yyyy"
              },
              {
                "value": "zzzz",
                "label": "zzzz"
              },
              {
                "value": "kkkk",
                "label": "kkkk"
              }
            ]
          }
        ]
      }
    ]
  },
  {
    "value": "bbb",
    "label": "bbb",
    "children": [
      {
        "value": "",
        "label": ""
      }
    ]
  }
]

Answer №1

Avoid the need for constructing JSON through string manipulation. Instead, focus on creating the data structure directly if you are planning to use JSON.parse(). Here's a way to achieve this:

function transform(data) {
    return Object.entries(data).map(([label, data]) => {
        const children = transform(data);
        return { value: label, label, ...children.length && {children} }
    });
}

// Example from the question
const a = {"aaa": {"aa": {"xxx": {"xxxx": {}}},"ab": {"xxx": {},"xxxx": {"xxxx": {}},"yyy": {"yyyy": {},"zzzz": {},"kkkk": {}}}},"bbb": {"": {}}}

console.log(transform(a));

If you ever require the JSON version of the resulting data structure, you can convert it by calling JSON.stringify.

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

Combining the Powers of Angular JS and Symfony2

Currently working on a project involving Symfony2 and in need of some advice. Considering a hybrid application approach in two ways: a) Using a traditional form with CSRF Token for the Login Page handled by Symfony2, and b) Inner pages (potentially module ...

core.js encountered an issue at line 6210: TypeError - The function this.service.addDepartment does not exist

Whenever I attempt to click the 'Add' button on a web application that I'm constructing, an error pops up. core.js:6210 ERROR TypeError: this.service.addDepartment is not a function at AddEditDepComponent.addDepartment (add-edit-dep.componen ...

Transmitting special symbols through Socket.io

I've been working on a small project based on Socketio 0.9 and everything is running smoothly, except for a minor problem with special characters. In the web client, I am creating a dynamic JSON object using JavaScript that is then emitted to the ser ...

Is there a way to avoid adding this final "faulty state" to the array?

While working on dynamically slicing an array, I noticed that my while loop was causing an extra slice to be added when it broke the conditional. Even though I can achieve the desired functionality by removing the last element with arr.pop(), I am curious ...

CKEditor not functioning properly when generated using AJAX and PHP in JavaScript file

I am facing an issue where I am using PHP and AJAX to generate a CKEditor textarea. The CKEditor JavaScript files are included in the main HTML file, and the PHP and AJAX functionalities are working correctly. However, when the form is displayed, the CKEdi ...

Accessing the i and i+1 elements within a ng-repeat iteration

I'm currently learning Angular and struggling with a seemingly simple issue. My goal is to achieve the following HTML structure in AngularJS: <div> <div> {{bar[i]}} {{bar[i+1]}} </div> <div> {{bar[i+2]}} ...

Redirecting with response headers in Next.js

Objective: The Goal: Clicking a button on a page should send a request to the controller. The controller will then set a cookie, and upon receiving the response, redirect the page to another page, such as the about page. Directly Calling API route from th ...

Have you ever wondered why the expression `Number(new Boolean(false))` always returns `0

In the case of Boolean(new Boolean(...)) === true, it is because new Boolean(...) is treated as an object. However, why does Number(new Boolean(false)) === 0 (+new Boolean(false) === 0) and Number(new Boolean(true)) === 1? Instead of resulting in NaN. Wh ...

Is it possible for me to add a string to a URL as long as the string is not null?

When retrieving data from a database, I have the option to include specific parts for a more targeted search. Let's say I have an object structured like this: { title: "wonderland", aliases: "", ... } My goal now is to generate a URL for the ...

Issue with Firebase Auth: Property 'auth' is undefined and cannot be read

I've been on a quest for answers everywhere to resolve this error. Strangely, my code was functioning perfectly fine last week but is facing issues today. I am trying to utilize Firebase auth to set up a sign-up page for my app, but I constantly encou ...

What is the best way to stop a jQuery function from applying titles extracted from the first row th's in thead's to multiple tables in a document?

My circumstances: I am new to jQuery and Stack Overflow, seeking assistance for my website project. The challenge: Building a website using Bootstrap 3.3.6 with intricate data tables that need to be stacked dynamically on mobile devices using CSS. It is c ...

Utilizing Ionic to import and parse an Excel file for data processing

I need assistance in uploading an Excel file and reading it using Ionic-Angular. I tried the following code, but it only seems to work for browsers and not for the Ionic app on Android. Can someone please help me with this issue? I am trying to read the E ...

I'm receiving an error message stating "mongoose.connect is not a function" while attempting to establish a connection with mongoose. Can you help me troub

I'm a beginner in Node.js and I'm currently working on creating a node/express/mongoose server app using TypeScript. Below is my app.ts file: // lib/app.ts import express from 'express'; import * as bodyParser from 'body-parser&a ...

Is it possible to overlook specific attributes when constructing an object using TypeScript interfaces?

I have defined an interface with various properties. I am looking to instantiate an object based on this interface, but I only want to partially initialize some of the properties. Is there a way to accomplish this? Thank you. export interface Campaign { ...

Issue encountered: Next.js has failed to hydrate properly due to a discrepancy between the initial UI and server-rendered content

Uncertain about the cause of this error? The error seems to disappear when I remove the provided code segment. What is triggering this error in the code snippet and how can it be fixed? <div className="relative flex flex-col items-center pt-[85.2 ...

Utilize Next.js with Axios for making an HTTP request to a Laravel Lumen endpoint, then showcase the retrieved data within the Next.js

I currently have a Next.js application that utilizes Axios to make calls to Lumen endpoints. The Axios HTTP client functions are organized in a separate folder named services/index.tsx, with sample code as follows: export const register = async (payload: a ...

It is imperative that the HTML div element remains within the boundaries of the page

Let me begin by providing some context. I am currently developing a responsive page that uses percentages to position my divs, allowing users to drag and drop items wherever they please. However, a problem arises when the user positions an object too close ...

Is there a way to implement an event listener for a customized select element within a table on a webpage?

I have a table that contains columns populated from a database. I also have a custom select dropdown in one of the columns, along with an update button. I want to create an event listener for the button that captures the user's selection from the cust ...

Removing undesired entries from a table view using AngularJs

In my table, there is a column called status which could have values like 'Open', 'Closed', 'Verified' and 'Rejected'. I am looking for a way to implement a filter in ng-repeat that will hide the rows with the statu ...

Tips for integrating my Python random forest classifier in a web application built using HTML, Javascript, and Node.js

Greetings! I am currently in the process of creating a machine learning web application that requires the use of a random forest classifier. However, I am unsure of how to properly integrate the python code with it. Any guidance would be greatly apprecia ...