Transforming a JSON structure into a tree model for use with the angular-tree-control component

I need help converting a complex JSON schema into a format compatible with Angular Tree Control. The issue is that the schema does not follow the required treemodel structure for Angular Tree Control, particularly because the children in the schema are not in an array. How can I transform this JSON schema into a treemodel format?

This is how the schema currently looks (although it's actually more intricate with multiple levels of nesting):

{
    "type": "object",
    "properties": {
        "firstName": {
            "type": "string"
        },
        "lastName": {
            "type": "string"
        },
        "address": {
            "type": "object",
             "properties": {
                 "addressLine1": {
                      "type": "string"
                  },
                  "addressLine2": {
                       "type": "string"
                  }
             }
         }
     }
 }

To display correctly in the Angular Tree Control, it should be structured like this:

{
        "type": "object",
        "properties": [
            {
                "name": "firstName",
                "type": "string"
            },
            {
                "name": "lastName",
                "type": "string"
            },
            {
                "name": "address",
                "type": "object",
                "properties": [
                      {
                          "name": "addressLine1",
                          "type": "string"
                      },
                      {
                           "name": "addressLine2",
                           "type": "string"
                      }
                ]
            }
        ]
    }

Answer №1

This example showcases the potential for refactoring code to enable recursion into deeper levels.

var objectData = {
    "type": "object",
    "properties": {
        "firstName": {
            "type": "string"
        },
        "lastName": {
            "type": "string"
        },
        "address": {
            "type": "object",
             "properties": {
                 "addressLine1": {
                      "type": "string"
                  },
                  "addressLine2": {
                       "type": "string"
                  }
             }
         }
     }
};

function createTreeModel(obj){
var treeModel = {};

for (var prop in obj) {
if(prop === 'properties'){
treeModel[prop] = []
var index = 0;
var count = 0;
for(subProp in obj[prop]){
if(obj[prop][subProp].type === 'object'){
treeModel[prop][index] = {name: subProp, type: obj[prop][subProp].type, properties: []};
for(innerProp in obj[prop][subProp].properties){
treeModel[prop][index].properties.push({name: innerProp, type: obj[prop][subProp].properties[innerProp].type});
count++;
}
} else {
treeModel[prop][index] = {name: subProp, type: obj[prop][subProp].type};
}
index++;
}
} else {
treeModel[prop] = obj[prop];
}
}
return treeModel;
}

var tree = createTreeModel(objectData);
// console.log(tree);
document.getElementById("output").innerHTML = JSON.stringify(tree, undefined, 2);
<pre id="output">
</pre>

Answer №2

This piece of code snippet is capable of handling nested structures as well

var details = {
      "type": "object",
      "properties": {
        "available": {
          "type": "boolean",
        },
        "size": {
          "type": "object",
          "properties": {
            "length": {
              "type": "integer",
            },
            "width": {
              "type": "integer",
            },
            "height": {
              "type": "integer",
            }
          }
   ...
}
    </div></answer2>
<exanswer2><div class="answer" i="57296988" l="4.0" c="1564587195" a="dmlqYXkga3VtYXI=" ai="7369067">
<p>This also includes support for nested structures</p>

<pre><code>var data = {
      "type": "object",
      "properties": {
        "checked": {
          "type": "boolean",
        },
        "dimensions": {
          "type": "object",
          "properties": {
            "width": {
              "type": "integer",
            },
            "height": {
              "type": "integer",
            },
            "volume": {
              "type": "object",
              "properties": {
                "length": {
                  "type":"integer",
                },
                "breadth":{
                  "type": "integer"
                }
              }
            }
          }
        },
        "id": {
          "type": "integer",
        },
        "name": {
          "type": "string",
        },
        "price": {
          "type": "number",
        }
      }
    }

// Function to find properties recursively
function findProperties(obj){
  let properties = []
  for(key in obj){
    if(obj[key].properties){
      properties.push({name: key, datatype: obj[key].type, properties: findProperties(obj[key].properties)})
    }else{
      properties.push({ name: key, datatype: obj[key].type});
    }
  }
  return properties;
}

// Function to parse the data and find properties
function findData(data){
  let result = "";
  for(key in data){
    if(key == 'properties'){
      result = findProperties(data.properties)
    }
  }
  return result;
}

console.log(JSON.stringify(findData(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

Using HTML5 video with cue points and stop points

I've noticed that there are various options available for implementing cuepoints in HTML5 videos, such as using PopcornJS or CuepointsJS to trigger play events at specific times within the video track. However, I am wondering if there is a solution t ...

Date range within a conditional statement

I have encountered this code snippet: function auto_select_param_call_time() { if (today() == date("02.01.2017") || today() == date("03.01.2017")) { auto_click_param("call_time", "Non-working day"); } else { //Do something else ...

Is there a way to have the ng-option initialize with the selected object value?

I am attempting to initialize this select element with a preselected option. However, the value I need to use is an object as shown in my code. The id that I require needs to be retrieved from data.selected. index.html <div ng-controller="MyCtrl">{ ...

Show JSON data in an HTML table using C# programming language

Hello there! I am relatively new to asp .net and currently working on a home project. I could really use some assistance here! My situation involves an ASP.NET Web API application with a textbox that takes the order number as a search string. To find my o ...

Controlling the maximum number of components displayed on each row in a loop or map using React

I'm having some trouble with this seemingly simple task and could use some guidance. Any suggestions would be greatly appreciated. Thank you. My Current Situation Currently, I am working with React.js and have an array containing 20 elements. What ...

AngularJS dual-stage resolution for resolving dependencies

I am facing a scenario where I must resolve one item before obtaining the data necessary to resolve another: .state('addtrip', { url: '/addtrip', templateUrl: 'views/addtrip.html', controller: &a ...

send a message to all clients using socket.io

I am having trouble figuring out how to broadcast a message from the client or another NodeJS file to all clients. While I was able to send messages to the server successfully, I am not able to reach every other client. Server code: var io = require(&ap ...

Leveraging Multiple MongoDB Databases in Meteor.js

Can 2 Meteor.Collections fetch data from separate MongoDB database servers? Dogs = Meteor.Collection('dogs') // mongodb://192.168.1.123:27017/dogs Cats = Meteor.Collection('cats') // mongodb://192.168.1.124:27017/cats ...

Dealing with multi-line strings in Javascript

I am having an issue with my code: let testStr = "Asdfads"; let htmlStr = `<script>${ testStr }</script>`; // but it works with: <div>${ testStr }</div> console.log(htmlStr); When I run this code, I receive the following error: ...

Seamless scrolling experience achieved after implementing a header that appears when scrolling up

My goal is to create a header with the following functionalities: Initially displays with a transparent background Upon scrolling down the page by 25px, it will dynamically add the header--maroon class to the header, which alters the background color and ...

Variations in CSS behavior for select and option elements

I have implemented the following HTML code snippet: <select ...> <option value=""></option> <option data-ng-repeat="type in xy" value="{{type.name}}" ng-style="{'border-left': '4px solid '+ type.color, &apos ...

When a div is clicked, the text inside the button changes. If another div is clicked, the previous text is reset

I am seeking a solution for changing the text of a button within three columns when a specific 'advice-card' div is clicked on. The text should change to 'Hide' for the clicked div, and the other buttons should switch back to 'Show ...

Issue with AngularJS Cross-Origin Resource Sharing (CORS) when making HTTP requests, whereas standard Ajax and jQuery are

I'm currently dealing with a straightforward cross-domain service that is set up to handle Simple CORS requests. When I try to access it using a plain xmlHTTP call or jQuery($.ajax), everything works smoothly. However, when attempting to make the call ...

Exclude chosen API responses prior to presenting them in the Table View

Dealing with data retrieved from an API through RestKit. My aim is to retrieve a list of businesses from the API, and I have successfully achieved that. However, on my end, I need to filter out any business classified as "McDonalds" before presenting the ...

Re-activate external script following a language update in Next.js

In my Next.js 13 app, I have implemented a live chat support button that is dynamically added based on the language selection. The code for rendering the button looks like this: import Script from 'next/script'; ... <div id={`onlinehelp-button ...

"After executing a loop in JavaScript using jquery.ajax, the success function does not perform

Having trouble passing values from a PHP file to another function in Javascript. Even after a successful FOR LOOP, nothing seems to work within the SUCCESS block. Any suggestions? url1 = 'http://localhost:81/Dashboard/admin/inc/dashboard.php'; $ ...

Adjusting the label on the Formik toggler

I have successfully implemented a switcher using Formik that changes the label accordingly with a boolean value. However, I now need to make the label reflect a string value instead of just "true/false." For example, I want it to display "Text1/Text2" inst ...

Tips for properly showcasing images on a webpage after ensuring all other content has loaded

Is there a way to have an image load last on a webpage after all other content has been loaded? I have an image that is retrieved from a database when a button is pressed, but I would prefer for the entire page to load first and then display the image. C ...

Creating a diverse layout by dynamically adding divs without achieving uniformity in the grid

I'm working on dynamically generating a grid of divs with a specific size using the code below: function createGrid(gridSize) { var container = document.getElementById('container'); for (var i = 0; i < gridSize; i++) { va ...

Utilizing Bootstrap combobox to easily select values by typing them in

I recently started utilizing the bootstrap combobox plugin on my website. Strangely, I've noticed that when selecting from the options in the dropdown list, choosing NewYork works smoothly. However, if I type "New" and attempt to select "New York" fr ...