Transform an object in javascript to HTML format

Looking for a function to convert a JavaScript object of this type:

{node: 'X', children: [{node: 'Y'}]}

into a string resembling HTML. For instance, the example above should be transformed to something like:

'<div class="X"><div class="Y"></div></div>'

The conversion should maintain the order in which nodes are nested inside each other as divs.

This is what I have so far:

function convertObj(obj){
  const html_start = '<div class="';
  const html_end = '</div>';
  let current_parent = obj;
  let child_nodes = '';
  
  if( typeof(current_parent.children) != 'undefined'){
    let children = current_parent.children.map(child_node => convertObj(child_node));
    child_nodes = child_nodes + children;
  }
  
  return html_start + current_parent.node + '">' + child_nodes + html_end;
}

The issue lies in the commas between child nodes when there are multiple of them. Here's my failing jest test:

describe('convertObj', () => {
  it('should turn node value into a div with the same name as its class', () => {
    expect(convertObj({node: 'A'})).toBe('<div class="A"></div>');
  });
  
  it('should insert child nodes into parent node', () => {
    expect(convertObj({node: 'A', children:[{node : 'B'}]})).toBe('<div class="A"><div class="B"></div></div>');
    
    expect(convertObj({node: 'A', children:[{node : 'B'}, {node: 'C', children: [{node: 'D'}]}]})).toBe('<div class="A"><div class="B"></div> <div class="C"><div class="D"></div></div></div>');    
  });
}); 

Any help would be greatly appreciated! Run tests here

Answer №1

By incorporating more ES6 syntactic shortcuts such as object destructuring and utilizing a template literal, you can create a straightforward recursive implementation:

const makeHTML = ({ node, children = [] }) =>
  `<div class="${node}">${children.map(makeHTML).join(' ')}</div>`

const treeData = {node: 'A', children:[{node : 'B'}, {node: 'C', children: [{node: 'D'}]}]}

console.log(makeHTML(treeData))

Answer №2

The issue arises from the automatic invocation of .join() when combining child_nodes (a string) and childrn (an array).

To resolve this problem, include an explicit .join() with a space as the separator, and your function will execute correctly.

function modifyObj(obj){
  const start_tag = '<div class="';
  const end_tag = '</div>';
  let parent_node = obj;
  let child_nodes = '';

  if( typeof( parent_node.children)!= 'undefined'){
    let children_array = parent_node.children.map(child => modifyObj(child) )
    child_nodes = child_nodes + children_array.join(" ");
  }

  return start_tag+parent_node.node+'">'+child_nodes+end_tag;
}

[{node: 'A', children:[{node : 'B'}]}, {node: 'A', children:[{node : 'B'}, {node: 'C', children: [{node: 'D'}]}]}]
   .forEach(test => console.log(modifyObj(test)));

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

Retrieving information from various object keys using Vue.js

Currently, I am in the process of setting up a feature in my application where users can select an option from a list and the background of the app will change based on their selection. Imagine having a list structured like this: <li v-for="item in it ...

Guide on creating a conditional column in a kendo UI grid with the use of AngularJS

Is there a way to dynamically add a column to the Kendo UI grid based on JSON data? Consider the following JSON input: [{ "ProductID": 1, "ProductName": "Chai", "Supplier": { "SupplierID": 1, "SupplierName": "Exotic Liquid ...

Trying to get a jQuery click function to trigger only once in CoffeeScript code

I've been searching high and low for a solution but nothing seems to be working. The issue I'm encountering is that I have a function that is supposed to post content to either a Facebook wall or a Twitter feed, but the click function only seems ...

Obtain the content of a dynamic text input field from a nested directive

I recently developed a custom directive using AngularJS that contains a child directive. The child directive's main task is to create various dynamic input elements like textboxes, radio buttons, and checkboxes, each with default values sourced from a ...

RectJs | Extract a parameter value from the url while disregarding any null values

Seeking assistance to retrieve the value of the "fruit" parameter from the URL in reactJs. Consider the following URL structure: http://localhost:3001/buy?fruit=&fruit=1&fruit=&fruit= Any of the four "fruit" parameters may contain a value, wi ...

What is the recommended way to emphasize an input field that contains validation errors using Trinidad (JSF)?

Trinidad currently displays error messages and highlights labels of failed inputs after client-side form validation. However, I need to directly highlight the input fields themselves. Is there a way to achieve this without resorting to a hack like attach ...

The autofocus feature does not function properly in an input tag that is not located within a form element

Is there a way to set the autofocus property in an input element that is not part of a form? I have tried adding the "autofocus" attribute to the input tag but it doesn't seem to be working. <div> //I have added the autofocus property her ...

Executing HTTP Requests for Elements in an Array using JavaScript

I am currently struggling with a script that sends HTTP requests to a website in order to obtain various documents. The document IDs are stored within an array, and my intention is to send a request for each element in the array and return a unique message ...

What is the best way to ensure my arrow text remains properly positioned when using fullpage.js?

Seeking guidance from the web development community. I am currently working on a client's website that utilizes fullpage.js and encountering a persistent issue. On slide1 of the website, I am struggling to display the correct text next to the arrows. ...

useEffect initiates all actions

I'm currently exploring hooks functionality within a Next.JS project. I've successfully used a useEffect to track scrolling behavior in order to dynamically change the content displayed in a header when the page is scrolled. const [ scrollY, setS ...

Firebase updates are not causing React components to update as expected

I've developed a people tracker for my smart home dashboard using React and Firebase. However, I'm facing an issue where the React component is not re-rendering when there are changes in the Firebase database. I'm unsure where I am making a ...

The chatbot text input feature is malfunctioning and failing to display the entered text in the chatbox

Hi there! I'm in the process of creating a chatbot using a basic input text box and button in HTML, with a php start function. Unfortunately, when I enter text into the textbox, nothing is showing up on the screen and the button doesn't seem to b ...

Placing information within a nested array with multiple levels of nesting

I'll try to keep this concise, Here is the structure of the schema... import mongoose from 'mongoose' const QuestionSchema = mongoose.Schema({ questionTitle: { type: String, required: " title"}, questionBody: { type: Stri ...

Ways to avoid browser refresh when uploading files in React applications

I'm working with a simple file upload form in React using hooks. import React, { useState } from 'react'; import { FlexContainer } from '@styles/FlexContainer'; const TestUpload = () => { const [file, setFile] = useState<F ...

Using only CSS to reverse the order of Bootstrap rows within a forEach statement in a .php file

I am facing a challenge in reversing rows within a forEach statement. For instance, in the first row, the content's div (title, text) should be on the left side and the image on the right side. In the second row, it should be reversed, with the image ...

Is it possible to use a JavaScript string as a selector in jQuery?

So, my issue is with the following JavaScript code snippet: for ( i=0; i < parseInt(ids); i++){ var vst = '#'+String(img_arr[i]); var dst = '#'+String(div_arr[i]); } I'm wondering how I can proceed in jQuery to handle ...

if the arguments for a javascript function are not provided

Currently, I am in the process of learning JavaScript through a book called "Visual Quickstart Guide". However, I have encountered a challenge with understanding the logic behind a particular code snippet. In the function definition below, it appears that ...

Various array outcomes are produced by identical JavaScript (SAP UI5) code

Utilizing cachebuster to identify the modified file in the application structure. Javascript code snippet: https://i.sstatic.net/CZGfW.png Ineffective Array result: https://i.sstatic.net/D6MdS.png Effective Array result: https://i.sstatic.net/pQCIh.p ...

VueJS - Input Image Display Issue Causing Browser Slowdown

I'm experiencing some issues with my VueJS component that includes a file input and displays an image afterwards. Strangely, this is causing my web browsers (both Firefox and Chromium) to freeze up and use massive amounts of CPU. I tried switching to ...

Obtain and utilize the background color to easily implement the same color in another window

For my Chrome Extension project, I am looking to retrieve the background color of the current page and then set the background color of a window to match. Can someone guide me on how to accomplish this using JavaScript (with or without jQuery), and if ne ...