Create a hierarchical survey system using a flat structure in JavaScript/TypeScript

I am working with a flat JSON data in TypeScript / JavaScript that needs to be structured hierarchically for creating a questionnaire later on.

Below are my TypeScript classes:

export class Template
{
    template_id: number;
    template_name: string;
    sections: Section[];
}

export class Section
{
    section_id: number;
    section_name: string;
    fields: Field[];
}

export class Field
{
    field_id: number;
    field_lable : string; //Typo fixed from "field_lable" to "field_label"
    input_type: InputType;
}

export class InputType
{
    input_type_id: number;
    input_type_name: string;
}

Example of flat data. It will eventually be a list of templates

templates: Template[];
[
   {
      "Template_id":1,
      "Template_Name":"Enterprise",
      "Section_id":1,
      "Section_Name":"Basic Info",
      "Field_id":1,
      "Field_Label":"Enter Your Name",
      "Input_Type_id":1,
      "Input_Type_Name":"Text"
   },
   ...
]

I'm interested in knowing if there are any lodash or similar libraries functions I can leverage

Expected Output:

[
   {
      "Template_id":1,
      "Template_Name":"Enterprise",
      "Sections":[
         {
            "Section_id":1,
            "Section_Name":"Basic Info",
            "Fields":[
               {
                  "Field_id":1,
                  "Field_Label":"Enter Your Name",
                  "Input_Type_id":1,
                  "Input_Type_Name":"Text"
               },
               ...
            ]
         },
         ...
      ]
   },
...
]

Answer №1

There may not be a convenient built-in function for this, but you can utilize the native reduce method to nest the data and have each class method with its own init function that can be recursively called.

const r = data.reduce((result, item) => {
    result[item.Template_id] = result[item.Template_id] || { id: item.Template_id, name: item.Template_Name }
    result[item.Template_id][item.Section_id] = result[item.Template_id][item.Section_id] || { id: item.Section_id, name: item.Section_Name}
    result[item.Template_id][item.Section_id][item.Field_id] = result[item.Template_id][item.Section_id][item.Field_id] || { id: item.Field_id, label: item.Field_Label}
    result[item.Template_id][item.Section_id][item.Field_id][item.Input_Type_id] = result[item.Template_id][item.Section_id][item.Field_id][item.Input_Type_id] || { id: item.Input_Type_id, name: item.Input_Type_Name }

    return result
}, {})

This process will give you a nested structure as shown below:

{
  "1": {
    "1": {
      "1": {
        "1": {
          "id": 1,
          "name": "Text"
        },
        "id": 1,
        "label": "Enter Your Name"
      },
      "2": {
        "1": {
          "id": 1,
          "name": "Text"
        },
        "id": 2,
        "label": "Enter Your Address"
      },
      "id": 1,
      "name": "Basic Info"
    },
    ...
    (Truncated due to space limitations)
    ...
  }
}

Subsequently, you can iterate over each template data and use the Template class to deserialize it. The Template class can then recursively call Section, Field, and Input classes within it.

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

I often find myself feeling unsure when I incorporate conditional logic in JSX within Next.js

Hello, I am currently using Next.js and encountering an issue with using if/else in JSX. When I use if conditions, the classes of elements do not load correctly. Here is my code: <Nav> { login ? ...

What is the best way to arrange a multi-dimensional array in JavaScript?

I need to organize an array in the following format, based on the numerical values in the first column. data = [ [5,"Title"],[3,"Title"],[1,"Title"],[2,"Title"],[4,"Title"] ]; Any suggestions on how to accomplish this task? ...

JavaScript and JQuery failing to sort list items on specific devices

My objective for this code: To alphabetize the list (from A to Z) Unexpected outcome: The list is alphabetizing on my laptop but not on my iPhone. I had to modify the conditional in the JavaScript due to the code defaulting to the else case. I'm h ...

Utilizing DataAnnotations in WebApi to Enhance Json Results

While utilizing ASP.NET WebApi to send results in JSON format, is it possible to include Data Annotations on the Model - ModelMetadata? For instance, attributes like DisplayName, ShowInEdit, ShowInDisplay, and other custom attributes along with Fieldname a ...

Is there a way to create a list in w2ui without including the -none- option?

Is there a way to create a list (select) in w2ui forms without the default -none- option? I would like to remove the default option and only display the items that I add to the list. How can this be achieved? ...

Issues with Adding Commas to Numerical Values

I've added a comma separator to display the total value that is being updated for roundNum: $.fn.digits = function(){ return this.each(function(){ $(this).text( $(this).text().replace(/(\d)(?=(\d\d\d)+(?! ...

angular primeng table has a checkbox to select all checkboxes

Is there a way to check all checkboxes in a table when the checkbox in the table header is clicked? I am currently utilizing angular 12 and primeNG table for this functionality. <p-table styleClass="text-sm" [value]="value" [loading] ...

Adding elements to an array in Node.js

In my 'both' object, I need to store 2 arrays: eng and fr. Each of these arrays contains multiple objects. How can I transfer all values from frDisplayData to fr:[] within the 'both' object: const displayData = []; var both = {eng:dis ...

The interface is unable to populate the Array of Elements

When using Angular, I send a request and save the response in a variable: conversations: Conversation[]; // ChatService getConversations() { return this.http.get<Conversation[]>('/chat/conversations'); } this.chatService.getConversat ...

Express JS appears to be returning undefined when trying to access req.body.content

Recently, I delved into the world of node and express. In an attempt to create a simple API for a note-taking application, I encountered an issue. When testing the API using POSTMAN to create a new note, the values of req.body.title and req.body.content re ...

Using TypeScript, you can access the constructor of a derived type by calling it with the

In my TypeScript project, I am attempting to generate or duplicate a child object using a method within the base class. Here is my simplified code setup: abstract class BaseClass<TCompositionProps> { protected props: TCompositionProps; prot ...

Sorting an ArrayList in Java with a comparator, beginning from the second object

If I have an ArrayList named arr with integers inside, such as: arr[0] = 7 arr[1] = 4 arr[2] = 1 arr[3] = 3 I aim to sort them excluding the first element (arr[0]), resulting in: arr[0] = 7 arr[1] = 1 arr[2] = 3 arr[3] = 4 Is there a way to ...

Unveil the picture and illuminate it using CSS styling

Currently, I'm trying to achieve a similar effect using CSS/js. https://youtu.be/HLJldmEw3q8 I've explored javascript animation frameworks like gsap in an attempt to create a simple image reveal with a glowing edge, but I'm finding it quit ...

Discovering routes in Angular2

I'm attempting to replicate something similar to this example here: AngularJS show div based on url/condition <span id="page-locator" *ngIf="location.path() == '/overview'">test</span> Unfortunately, it's not working as ex ...

Encountered a problem when attempting to access an element on a PHP page using

My javascript code is supposed to retrieve information from a specific URL (song.php) which contains the name of a song. However, there seems to be an issue as the javascript is not extracting the required data. Below is the HTML element and javascript fo ...

Charts.js fails to refresh data following an AJAX call

Having recently delved into the world of js and jquery, I managed to successfully display a chart using Flask and an Ajax request. However, I've hit a roadblock when it comes to refreshing the charts data. If I create a new chart each time as demonstr ...

Locating the elusive sequence number within a document

Greetings, I am currently trying to locate a missing number within an xml file but seem to be encountering some challenges. Any suggestions or ideas would be greatly appreciated. Example The file contains an <a> tag with various ids such as page-1, ...

Each click toggles between showing and hiding all items

Every time I click on an item, I want to toggle only that specific item instead of toggling all items simultaneously. This functionality is implemented using the useContext API. import React, { useState, useEffect } from "react"; const MyContext ...

Netbeans Error: Application crashing during runtime with 2D dynamic array

I have a task to create a 2D dynamic array with a size equal to M*M (user input), where both the column and row are of the same size M. The issue I'm facing is that after entering values for M and K, the application crashes. I am struggling to grasp ...

Combining mouse interactions with animated bar transitions

I want to create a graph with dynamic bar height transitions whenever it is drawn or redrawn. Once the bars are displayed, I would like mouse events (mouseenter, mouseleave, and mousemove) to trigger a tooltip showing information about the specific bar bei ...