0

I've got this code and I need to transform ti to DOM structure (more information below)

const data = [
  {
    "type": "paragraph",
    "children": [
        {
            "type": "text",
            "text": "Hey all!"
        },
        {
            "type": "break"
        },
        {
            "type": "break"
        },
        {
            "type": "text",
            "text": " It's been a while since we partied "
        },
        {
            "type": "important",
            "children": [
                {
                    "type": "text",
                    "text": "together"
                }
            ]
        },
        {
            "type": "text",
            "text": " in a pool full of people!"
        }
    ]
},
{
    "type": "heading",
    "id": "table-of-contents",
    "level" : 2,
    "children": [
        {
            "type": "text",
            "text": "Table of contents:"
        }
    ]
},
{
    "type": "list",
    "bullet": "decimal",
    "children": [
        {
            "type": "listitem",
            "children": [
                {
                    "type": "anchor",
                    "href": "#table-of-contents",
                    "children": [
                        {
                            "type": "text",
                            "text": "How to start a podcast?"
                        },
                        {
                            "type": "text",
                            "text": ""
                        }
                    ]
                },
                {
                    "type": "text",
                    "text": "Where to find your topics?"
                }
            ]
        },
        {
            "type": "listitem",
            "children": [
                {
                    "type": "text",
                    "text": "Where to find your topics?"
                }
            ]
        },
        {
            "type": "listitem",
            "children": [
                {
                    "type": "text",
                    "text": "What equipment do you need?"
                }
            ]
        }
    ]
}
]

What is the best way to do it?

I mean, should I do

const wrapper = document.createElement("div");

data.forEach(element => {
    if(element.type === "paragraph") {
        const paragraph = document.createElement("p");

        element.children.forEach(kiddo => {
            if(kiddo.type === "text") {
                const textNode = document.createTextNode(kiddo.text);

                paragraph.appendChild(textNode);
            }
        });
    }
})

..and so on? I mean do I have to use "createElement/createTextNode" functions or does javascript have some kind of DOMBuilder than I can convert such structure into DOM?

2
  • Put the tasks of the different types in an object (ex. types) as methods, iterate the data recursively, and call a suitable type method from types object on every type. You've also to keep book of the parent element to append the newly-created HTML element. Commented Jul 22, 2020 at 16:17
  • "I mean do I have to use "createElement/createTextNode" functions or does javascript have some kind of DOMBuilder than I can convert such structure into DOM?" - Yeah, it has HTML. Commented Jul 22, 2020 at 16:23

1 Answer 1

2

As Teemu says, you can create your own "DOM Builder" by adding methods to an object and recursing.

    const body = document.getElementsByTagName("body")[0];
    const wrapper = document.createElement("div");

    const DOMBuilder = {
        "anchor" : e => { 
            var a = document.createElement("a"); 
            a.href = e.href; 
            return a; 
        },
        "heading" : e => { return document.createElement("h" + e.level); },
        "list" : e => { 
            return document.createElement((e.bullet == "decimal") ? "ol" : "ul"); 
        },
        "listitem" : () => { return document.createElement("li"); },
        "paragraph" : () => {return document.createElement("p"); },
        "text" : e => {return document.createTextNode(e.text); },
    }

    function CreateDOMElement(e) {
        var ne;
        if (ne = DOMBuilder[e.type]?.(e)) {
            if (e.id) ne.id = e.id;
            e.children?.forEach(c => { 
                var ce = CreateDOMElement(c); if (ce) ne.appendChild(ce); 
                });
            return ne;
        }
    }

    data.forEach(element => { 
        var ne = CreateDOMElement(element); if (ne) wrapper.appendChild(ne); 
        });
    body.appendChild(wrapper);
Sign up to request clarification or add additional context in comments.

1 Comment

hey Justin, thanks. I was thinking the same, but really wanted to post here, to see if there would be a different solution. anyways, this is also the most convenient to write. so thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.