Tips for modifying JSON response using a function

When I call the function buildFileTree, I store its response in a constant variable called data.

const data = this.buildFileTree(dataObject, 0);

The value of dataObject is:

 const dataObject =  JSON.parse(TREE_DATA);

And the content of TREE_DATA is:

const TREE_DATA = JSON.stringify([
{
    Standard: "Food",
    Category: [
      {
        Name: "Vegetable",
        Tables: [
          {
            Description:
              "The carrot is a simple root vegetable, usually conical or cylindrical in shape.",
            Name: "Carrots"
          },
          {
            Description:
              " tomatoes come in a wide variety of shapes: round, oblate, pear-shaped, torpedo-shaped,",
            Name: "Tomatoes"
          }
        ]
      },
      {
        Name: "Fruits",
        Tables: [
          {
            Description: "Oranges",
            Name: "Spherical shape is of orange"
          },
          {
            Description: "Grapes",
            Name:
              "Grapes are typically an ellipsoid shape resembling a prolate spheroid."
          }
        ]
      }
    ]
  }
]);

The buildFileTree function is defined as follows:

buildFileTree(obj: { [key: string]: any }, level: number): FileNode[] {
    return Object.keys(obj).reduce<FileNode[]>((accumulator, key) => {
      const value = obj[key];
      const node = new FileNode();
      node.filename = key;
      if (value != null) {
        if (typeof value === "object") {
          node.children = this.buildFileTree(value, level);
        } else {
          node.type = value;
        }
      }
      return accumulator.concat(node);
    }, []);
  }
}

The output generated from the function execution is displayed as:

Current Response

Desired Result : Format

It appears that modifications may be necessary in the buildFileTree function. Can someone assist me with this matter?

A live example showcasing the current response can be accessed here: https://stackblitz.com/edit/angular-qsb9c8-x4oaan?file=app%2Ftree-nested-overview-example.ts

Answer №1

To avoid the unnecessary step of converting the array into JSON and then restructuring it, you can directly manipulate the treeData array by looping through each object and organizing the desired data as shown below:

var treeData = [
    {
      Standard: "Technology",
      Subcategories: [
        {
          Type: "Software",
          Products: [
            {
              Description:
                "Operating systems like Windows...",
              Name: "Windows"
            },
            {
              Description:
                "Applications such as Microsoft Office...",
              Name: "Microsoft Office"
            }
          ]
        },
        {
          Type: "Hardware",
          Products: [
            {
              Name: "Laptops",
              Description: "Portable computing devices"
            },
            {
              Name: "Smartphones",
              Description:
                "Mobile phones with advanced features."
            }
          ]
        }
      ]
    }
  ];
  
let structuredData = {};

for (const obj in treeData) {
  const subcat = {};
  treeData[obj].Subcategories.forEach(e => {
    subcat[e.Type] = e.Products.map(i => i.Name)
  });
  structuredData[treeData[obj].Standard] = subcat;
}

console.log(structuredData);


If you need to loop over this structure in a template, you can utilize the following code snippet:

<div *ngFor="let category of structuredData | keyvalue">
    {{ category.key }}
    <ul *ngFor="let subcategory of category.value | keyvalue">
        <li>{{subcategory.key}}</li>
        <ul *ngFor="let product of subcategory.value | keyvalue">
            <li>{{product.value}}</li>
        </ul>
    </ul>
</div>

Answer №2

The issue with your function arises from applying it to a Javascript Object in the example, even though your TREE_DATA is actually a Javascript Array.

If you use the Object.keys() method on an array, it will return the indexes of the elements in the array. For example:

Object.keys([10,20,30]); // returns ['0','1','2']

To correct this, you should adjust your buildFileTree function as shown below:

// Create a new JavaScript object where each key represents a 'Standard' entry and its value
// is another object containing 'Category.Name' as the key and an array of all entries' Names as the value 

const result = dataObject.reduce((acc1, e1) => {
  acc1[e1.Standard] = e1.Category.reduce((acc2, e2) => {
    acc2[e2.Name] = e2.Tables.map(e => e.Name);
    return acc2;
  }, {})
  return acc1;
}, {});

I hope this clarifies things for you! If you're not familiar with the reduce and map methods, I recommend looking into them!

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

Configuring Google Chart LineChart settings by utilizing the series attribute

I am looking to modify the options for my line chart. However, when I define the options as shown below, the first series setting gets ignored and only the second series property is applied. var options = { title: 'Temperature Graph ( sampling ev ...

The React functional component fails to update when triggered by a parent component's setState method

My React component is utilizing apollo to fetch data through graphql class PopUpForm extends React.Component { constructor () { super() this.state = { shoptitle: "UpdateMe", popupbodyDesc: "UpdateMe" } } re ...

Ensure that the div remains within the viewport

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Tit ...

How can one generate an HTML element using a DOM "element"?

When extracting an element from an HTML page, one can utilize a DOM method like .getElementById(). This method provides a JavaScript object containing a comprehensive list of the element's properties. An example of this can be seen on a MDN documentat ...

Code snippet in webpage body

Hey there, I could really use some assistance: I currently have the following: A) Login.html B) Documentation.html C) Base.html Within the login page, there is a form with fields for User and Password. In Documentation, there are links to various folder ...

What exactly is a NativeScript app: is it the experience users have on their mobile devices, or the product they download from the app store?

Currently, I am diving into the world of Angular and exploring how to develop Angular applications with TypeScript while working on a C# ASP.Net Core Web Api project as the server side component. My question is this - if I create a NativeScript app in add ...

What could be causing the issue with uglify not functioning properly with AngularJS content?

I've created some gulp tasks to assist in building my web project. One of the tasks involves minifying js files. Here is the task code snippet: gulp.task('minify' , function() { console.log('Copy minified js '); return gulp ...

The required dependencies for @angular/[email protected] and @angular/[email protected] have not been fulfilled

Details: npm version: 3.10.10 and nodejs version: 6.11.1 I am in the process of setting up a .NET project with an angular web API but am encountering unmet dependencies: "unmet peer dependency @angular/[email protected] and @angular/[email prote ...

Setting a default value for Autocomplete in MaterialUI and React.js

Is there a way to set a default value for an Autocomplete TextField component from Material UI in React.js? I want to load a pre-populated value from the user's profile that can then be changed by selecting another option from a list. Check out my co ...

How can you show the default calendar for a specific month and year in a Vue3 datepicker?

I've been utilizing the @vuepic/vue3datepicker component, which automatically shows the days of the current month when integrated in my project: <template> <VueDatePicker v-model="date" inline></VueDatePicker> </templ ...

Creating a PDF file with Angular 7: A step-by-step guide

I need to create a PDF report using data provided by the user and save it in an object. I've encountered methods that involve creating an HTML page, taking a screenshot, and then converting it to PDF. However, I'm seeking a solution to generate a ...

There is no universal best common type that can cover all return expressions

While implementing Collection2 in my angular2-meteor project, I noticed that the code snippets from the demo on GitHub always result in a warning message being displayed in the terminal: "No best common type exists among return expressions." Is there a ...

Issue with binding classes dynamically in vue with svg elements

I'm attempting to create a custom typing program for one of my students using SVG to display the words and class binding with Vue.js. The goal is to change the color of the characters when the correct key is pressed by the user. However, I've enc ...

What is the best way to extract and format data from a database using unserialize, json decode, or implode functions in Laravel Blade?

After collecting data from a form using various methods such as Serialize, Implode, and Json_encode, the stored information looks something like this: Serialized Data +-------+----------------------------------------+------------------------------- ...

Error: Unable to call dispatch method on this.$store object

I'm diving into Vue and hitting a wall with this error message. TypeError: this.$store.dipatch is not a function I've set up the store.js file and am attempting to call actions from within a vue file. I've scoured the internet for answers ...

Why does VSCode open a React app in Edge instead of Chrome?

Recently, I began a new project using the react-create-app template with typescript. However, when I run npm run dev, it unexpectedly opens in the Edge browser instead of Chrome. Does anyone know how to make it open in Chrome instead? ...

Error Event Triggered by AJAX with No Response Data

I am currently facing an issue with an API call I am making. Everything seems to be working fine as I receive the token and a status code of 200 is returned (confirmed in Fiddler). However, the problem arises when the AjaxError event fires and the respon ...

Uploading images in React JS by allowing users to paste images

Currently working on a chat application using React JS and I'm looking to enable image uploading when an image is pasted into the chatbox. How can I make this happen? Essentially, I am in need of: An event that will activate upon performing the "Pas ...

Enabling cookie communication between NestJS server and Next.js frontend

I seem to be encountering challenges when trying to set cookies from a NestJS backend into my Next.js app. My NestJS application is running on port 3001 and here is my bootstrap setup: async function bootstrap() { const app = await NestFactory.create(Ap ...

Error: The variable 'err' is not declared in this scope.at line app.post

Tools I am Using Windows 10 Firebase (Firestore) Postman JavaScript, Express I'm learning from this video(https://www.youtube.com/watch?v=-vo7cu0xP4I) Situation Description I attempted to make a post request using Postman for testing purposes, b ...