I am getting started with react-jsonschema-form, It requires input in a particular format. I am given a nested JSON but i am unable to recursively mutate the JSON according to the required input format.
Given is this JSON
{
"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"
}
}
And this new JSON is needed to be generated recursively.
{
"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": "Start 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"
}
}
}
}
I am able to achieve this using iterative format but that is not scalable. And i have been stuck for hours to get this in recursive method.
I would really appreciate if i get a recursive method to update this given JSON to the required format in javascript
.
I think this gets it done. Let me know if you see something I missed.
// input data copied from question
const input = {
"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"
}
};
// recursive field conversion function
const convertField = (key, value) => (
{
type: typeof value, // 'object', 'boolean', 'number', 'string'
title: key, // field name is also the title (e.g. 'Starting Range')
...(
typeof value !== 'object'
? { default: value } // primitive type. default and we're done
: {
properties: Object.entries(value)
.reduce((facc, [field, fvalue]) => ({
...facc, // keep previous iterations
[field]: { // keep the field name, e.g. 'Starting Range',
...convertField(field, fvalue) // recurse for the field's value
}
}), {})
}
)
}
);
// kick it off
const output = Object.entries(input)
.reduce((acc, [key, value]) => ({
...acc, // retain previous iteration results
[key]: {...convertField(key, value)} // convert each property
}), {}
);
// show the results
document.getElementById('result').innerText = (JSON.stringify(output, null, 2))
<pre id="result" />