0

Need some help over here. Been bashing my head against a piece of code for a while now, but I can't wrap my head around it. Slowly trying to learn JavaScript, and trying to handle a piece of JSON data.

The JSON data is as follows. (simple example, more nesting going to happen at some point)

{
    "div": {
        "attr-id": "josh",
        "div": {
            "attr-id": "greg"
        }
    }
}

(So far so good, right?) Well, now I'm trying to make this into HTML. First I did some for loops, I tried using "classes", nested functions, etcSo I figured a recursive function would be suitable. Oh, yes, let me get right on that! head explodes

I've been trying various functions, trying to find something as lean and mean as possible. The theory is:

Send parsed JSON to function. Function finds first property. If property value is an object then get property key to be used as value for a document.createElement(v). Else if property value is a string, that means there's an "attr" present. And we need to apply this to our element. However, what if the element isn't there yet? here's when my brain has starts to speed wobble). Anyway if the key value is an object, we would want to call the function again, this time supplying this data. And also, since we're handling elements. We'd want to append this outcome to our previous element. Eh..

I've discarded so much code, and I'm having a hard time wrapping my head around recursion, or simple the laws of javascript. I haven't gotten further than this I'm afraid and this code doesn't even work.

function recurseYou(obj) {
    for(var key in obj) {
        //probably a safer way testing than typeof = string
        //but this'll have to do for now
            if(typeof obj[key] != 'string'){
                //create a new element
                var el = document.createElement((key.split("."))[0]);
                //append the return of the function using the 
                //current key value
                el.appendChild(recurseYou(obj[key]));
            } else {
                // do stuff to string
            }
        }
    return el;
}

Anyway, any pointers, tips or help very appreciated. But please keep it to JavaScript only, I'm not interested in solutions using libraries at this point!

5
  • Wouldn't it be a lot easier to just send HTML, if that's what you want anyway ? Commented Oct 30, 2014 at 21:29
  • 1
    Your child nodes should be an array of node descriptor objects, instead of abusing properties named after tags for this. Commented Oct 30, 2014 at 21:31
  • @adeneo yeah, maybe your right. I took it as a learning experience, and I like how JSON feels.. if that makes sense.. Commented Oct 30, 2014 at 22:31
  • @Bergi in a controlled environment, what is the downside? I'm curious Commented Oct 30, 2014 at 22:32
  • It's not about controlled environments, it's simply about being limited to a single child element. Commented Oct 30, 2014 at 23:00

1 Answer 1

2

Rather than return an element (since you don't have a single element to return when you may be presented with a list of elements), pass in a parent (e.g. document.body) and append to that:

var o = {
    "div": {
        "attr-id": "josh",
        "text": "josh text",
        "div": {
          "attr-id": "greg",
          "text": "greg text"
        }
    }
};

function recurseYou(obj, parent) {
  for(var key in obj) {
    if (typeof obj[key] === 'object'){
      var tag = (key.split("."))[0];
      var el = document.createElement(tag);
      parent.appendChild(el);
      recurseYou(obj[key], el);
    } else if (key === "text") {
      var txt = document.createTextNode(obj[key]);
      parent.appendChild(txt);
    } else if (key.match(/^attr-/)) {
      var matches = key.match(/^attr-(.+)/);
      var vari = matches[1];
      var value = obj[key];
                
      parent.setAttribute(vari, value);
    }
  }
}

recurseYou(o, document.body);
#josh {
  color: blue;
}

#greg {
  font-weight: bold;
}

Sign up to request clarification or add additional context in comments.

1 Comment

Nice, I played around with the parent thingy but couldn't get it to work. Thanks a lot, will mark this as answer. Just one little edit, the last line sets var el to equal recurseYou which no longer is needed.

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.