Transforming JSON to function with react-jsonschema-form

Starting off with react-jsonschema-form, I've encountered the need for input in a specific format. Unfortunately, dealing with nested JSON data has proven to be challenging when trying to recursively transform it into the required format.

The initial JSON structure is as follows:

{
  "Coordinates": {
    "X-Coordinate": 47,
    "Y-Coordinate": -122
  },
  "Coordination Type": {
    "Cartesion Mode": false,
    "Starting Range": {
      "Start": 8000,
      "End": 9000
    }
  },
  "Map": {
    "Offline Map": false,
    "URL": "http://localhost:9000"
  }
}

Here is the desired recursive transformation of the JSON data:

{
   "Coordinates": {
    "type": "object",
    "title": "Coordinates",
    "properties": {
      "X-Coordinate": {
        "type": "number",
        "title": "X-Coordinate",
        "default": 47
      },
      "Y-Coordinate": {
        "type": "number",
        "title": "Y-Coordinate",
        "default": -122
      }
    }
  },
  "Coordination Type": {
    "type": "object",
    "title": "Coordination Type",
    "properties": {
      "Cartesion Mode": {
        "type": "boolean",
        "title": "Cartesion Mode",
        "default": false
      },
      "Starting Range": {
        "type": "object",
        "title": "Starting Range",
        "properties": {
          "Start": {
            "type": "number",
            "title": "Start",
            "default": 8000
          },
          "End": {
            "type": "number",
            "title": "End",
            "default": 9000
          }
        }
      }
    }
  },
  "Map": {
    "type": "object",
    "title": "Map",
    "properties": {
      "Offline Map": {
        "type": "boolean",
        "title": "Offline Map",
        "default": false
      },
      "URL": {
        "type": "string",
        "title": "URL",
        "default": "http://localhost:9000"
      }
    }
  }
}

Even though an iterative approach was initially successful, it lacks scalability. Hence, I've been struggling for hours to develop a recursive method for this transformation.

I would greatly appreciate guidance on implementing a recursive JavaScript function to adapt the given JSON data to the specified format.

Answer №1

Looks like this should do the trick. Please let me know if you notice anything I may have overlooked.

// input data copied from the initial inquiry
const userInput = {
  "Coordinates": {
    "X-Coordinate": 47,
    "Y-Coordinate": -122
  },
  "Coordination Type": {
    "Cartesion Mode": false,
    "Starting Range": {
      "Start": 8000,
      "End": 9000
    }
  },
  "Map": {
    "Offline Map": false,
    "URL": "http://localhost:9000"
  }
};

// function for recursively converting fields
const fieldConverter = (field, value) => (
  {
    type: typeof value, // possible values are 'object', 'boolean', 'number', 'string'
    title: field, // using the field name as the title (e.g. 'Starting Range')
    ...(
      typeof value !== 'object'
      ? { default: value } // primitive type; set default and end recursion
      : {  
        properties: Object.entries(value)
          .reduce((convertedValues, [subField, subValue]) => ({
            ...convertedValues, // retain previous iterations
            [subField]: { 
              ...fieldConverter(subField, subValue) // recursive call to handle nested objects
            }
          }), {})
      }
    )
  }
);

// starting point of conversion
const convertedOutput = Object.entries(userInput)
  .reduce((result, [key, value]) => ({
    ...result, // keep track of previous results
    [key]: {...fieldConverter(key, value)} // convert each property
  }), {}
);

// display the result
document.getElementById('output').innerText = (JSON.stringify(convertedOutput, null, 2))
<pre id="output" />

Answer №2

Utilizing the JSON.parse reviver parameter enables transformation of values :

var jsonData = `{
  "Coordinates": {
    "X-Coordinate": 47,
    "Y-Coordinate": -122
  },
  "Coordination Type": {
    "Cartesion Mode": false,
    "Starting Range": {
      "Start": 8000,
      "End": 9000
    }
  },
  "Map": {
    "Offline Map": false,
    "URL": "http://localhost:9000"
  }
}`

var parsedObj = JSON.parse(jsonData, (key, value, type = typeof value) => !key ? value : 
  { type, title: key, [type === 'object' ? 'properties' : 'default']: value } )
  
console.log(parsedObj)

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

Creating a dynamic jQuery method to apply validation rules to multiple fields

I am currently utilizing the jQuery validation plugin to validate a dynamically generated form. Specifically, I have multiple email input fields created within a PHP loop: <input type="text" name="customer_email_<?=$i?>" value="" id="customer_ema ...

Get access to environment variables dynamically using parameters

I'm currently developing a Vue plugin to retrieve the content of environment variables, similar to PHP's env() method. Background: I require a URL in multiple components and have stored it in the .env file anticipating potential future changes. H ...

What is the best way to deserialize JSON arrays and connect the extracted objects to WPF DataGrids?

If I have a JSON file that contains two arrays - one named "people" and the other named "places": { "people": [{ "name": "Adam", "age": 24 }, { "name": "Bill", "age": 26 }, { "name": "Charlie", " ...

What is the best way to assign a class to certain columns within a table?

I'm working on a code that generates random numbers for 3 columns and checks if each generated number exceeds +5/-5 of its previous number. However, I've encountered an issue where the first two columns always have the "blink" CSS applied to them ...

Prevent user input in HTML

Currently, I am working on creating the 8 puzzle box game using JavaScript and jQuery Mobile. The boxes have been set up with <input readonly></input> tags and placed within a 9x9 table. However, an issue arises when attempting to move a box ...

Making a surface-level copy of an array containing nested arrays

I am facing an issue with manipulating child arrays within a parent array. Specifically, I want to manipulate the first element in the first child array without affecting the rest of the arrays. However, my current code is shifting the first elements of al ...

Using AJAX to submit a single form

Within my HTML view, I have multiple forms that are displayed using a PHP foreach loop. One of the form examples is as follows: <form method="POST" class="like-form-js"> <input type="hidden" name="post_id" value="<?= $post['i ...

The choice between using inline style objects with React or utilizing traditional CSS classes presents distinct advantages and

Is there a discernible difference between utilizing an inline style object for react components and using a normal CSS class through the className attribute? Even when wanting to modify styles based on a specific event, simply changing the className should ...

Creating multi-line tabs using Vuetify

I am currently using Vuetify to design the layout for my web application. I have implemented a tabbed navigation system at the top of the page and I am looking to achieve a specific visual effect. https://i.sstatic.net/o17d0.png I have experimented with ...

Combining various postponed JavaScript file imports in the HTML header into a single group

I've been facing an issue with my code structure, particularly with the duplication of header script imports in multiple places. Every time I need to add a new script, I find myself manually inserting <script type="text/javascript" src=&q ...

Automatically hide a label after a certain amount of time following a button click

Currently, I am working with ASP.NET and C#. Within my application, there is a registration form that includes a label to display the status of registration, either success or failure. The content of this label is determined dynamically in the codebehind ...

Update the value of the following element

In the table, each row has three text fields. <tr> <td><input type="text" data-type="number" name="qty[]" /></td> <td><input type="text" data-type="number" name="ucost[]" /></td> <td><input ty ...

"Uncaught ReferenceError: $ is not defined - $function()" error in JavaScript/jQuery

When attempting to execute a JavaScript/jQuery function, an error is encountered when using Firebug: $ is not defined $(function()". The issue arises from the placement of the JavaScript code within a file named core.js that is referenced by index.php. W ...

Converting an HTML menu to a WordPress menu: A step-by-step guide

Hey everyone, I've got some code in my HTML file that's using the 320 Bootstrap WP theme. I've created a menu and it's working fine. However, the box above the menu isn't moving along with it from menu to menu. Any ideas on how to ...

Utilize the _sortBy function from the lodash library to arrange an array based on a specific field

Looking at an array of objects similar to this: myArray = [ {AType: "aaa", Description: "De", …}, {AType: "bbb", Description: "Hi", …}, {AType: "ccc", Description: "Un", …}, {AType: "ddd", Description: ...

Iterate through the JSON response once the AJAX call is successful

Apologies for the duplication, this question was originally asked on Stack Overflow, but as a newcomer to this topic, I am seeking guidance on how to achieve it? Below is my AJAX call: $("#btnprocess").click(function () { $.ajax({ ...

How can I show or hide a survey pop-up depending on the URL in the address bar?

There are 2 different applications in play here. My application is built using Angular for the front end and can be accessed at http://test.com/search. It includes a JavaScript function that triggers a survey popup whenever a user visits our website. Anot ...

`<picture> contains the main image``

Is it possible to access the currently displayed source of a <picture> element in JavaScript without relying on viewport width or pixel density? Looking for a method similar to <select>:selected If anyone has insights on this, please share! ...

Tips for dynamically updating an input within a shadow DOM using code?

Snippet: https://jsfiddle.net/5zrwdjy7/2/ I'm currently working on automating keystrokes with a script within Cypress, however, the target website I am dealing with utilizes web components as inputs. These input elements are nested inside what is kno ...

Exploring the transparency of material lab autocomplete drop-down text for enabling multiple selections

Check out this demo for checkboxes and tags in Material UI The code below demonstrates an autocomplete component that functions correctly. However, the drop-down text appears transparent. Is there a way to fix this issue without modifying any libraries? ...