1

I thought this would be a simple task, but I've been working on this all day but still can't seem to figure it out.

I am receiving a very large (multiple layers of objects) JSON file which I stored in a state of my component, now I need to render that data on the screen. This has become difficult, because within the object I have several others objects which also may contain other objects.

So far, I am using Object.keys(myJSONObject).map(...) to try to get it done, however I can't seem to find a way to reach all the 'sub-objects'. Here is my current code:

render: function(){
       return (

        <div>

            {
                Object.keys(_this.state.content).map(function (key) {
                     if (typeof _this.state.content[key] instanceof Object){
                  //go through all objects and sub-objects???

                        }
                    return <div > Key: {
                        key
                    }, Value: {
                                _this.state.content[key]

                    } </div>;
                })
            }


        </div>
    );
   }

Edit: I should probably add that my object is _this.state.content

Edit 2: Here is an example of the object I am looking to iterate through. Keep in mind that is it a lot bigger than this.

{ "3.8": [ "Something something" ], 
 "3.2": [ { "Blabla": [ "More things I am saying", "Blablablabal", "Whatever" ] } ],
 "2.9": [ { "Foo": [ "bar", "something something something something", "blablablabalbalbal" ] } ]} 

Edit 3: Here is how I would somewhat like it to look when rendered:

3.8:
 - Something something
3.2:
 - Blabla:
     - More things I am saying
     - Blablablabal
     - Whatever
2.9:
 -Foo:
     -bar
   ...
theJuls
  • 6,788
  • 14
  • 73
  • 160
  • map iterates 1 level by default, you need to make a recursive function if you want to dig into the sub levels. – ajmajmajma Sep 28 '16 at 20:04
  • is there an example of how to do that somewhere? – theJuls Sep 28 '16 at 20:04
  • You should show the object you are trying to iterate through, even if it's just an example. Even better if you have a fiddle with the component and state object in it or something! – ajmajmajma Sep 28 '16 at 20:06
  • By JSON object you mean JavaScript object, right? [There is no such thing as a "JSON Object"](http://benalman.com/news/2010/03/theres-no-such-thing-as-a-json/) . *"I can't seem to find a way to reach all the 'sub-objects'."* You may need recursion. See [Access / process (nested) objects, arrays or JSON](http://stackoverflow.com/q/11922383/218196) – Felix Kling Sep 28 '16 at 20:08
  • @ajmajmajma I added an example of what it somewhat looks like in an edit. – theJuls Sep 28 '16 at 20:12
  • @FelixKling yes, that is exactly what I meant! (what I meant by JSON object was that it was an object made from the JSON data. Sorry about that...) Thanks for the link I will take a look over it right now. – theJuls Sep 28 '16 at 20:14
  • And what is the intended result? Your strings are all in arrays, is the value suppose to be all of the strings or just one? Can you show what the rendered results should look like? – ajmajmajma Sep 28 '16 at 20:31
  • @ajmajmajma I want to print pretty much all of the contents in there (all of the strings, including the keys). I would like them all to rendered in a tree-like structure, were the outer nodes are parents of the inner ones, if that makes sense. – theJuls Sep 28 '16 at 20:36
  • @ajmajmajma I will add that to the edit because I don't think I expressed myself appropriately – theJuls Sep 28 '16 at 20:37

2 Answers2

1

Here is a code which I wrote sometime back to handle 3 layers of nesting in my json file.

JSON

var a = {
    "parent":{
       "name":"x",
       "child":{
          "name":"y",
          "subchild":{
                "name":"check"
          }
       }
  }
}

Iterator

  Object.keys(obj).map(function(key,index){
    let section = obj[key]
    //getting subsections for a single section
    let subSections = section["subsections"] // get you nested object here
    Object.keys(subSections).map(function(subSectionId,key){
      //getting a single sub section
        let subSection=subSections[subSectionId]
      //getting instruments for a sub section
      let  nestedSection = subSection["//key"] //get you next nested object here

         Object.keys(instruments).map(function(instrumentId,key){
                    //operation
                 }
             })
         })
    })
  })

Hope it helps.

Harkirat Saluja
  • 7,768
  • 5
  • 47
  • 73
  • Thank you for the help. Unfortunately it won't work for me :( As it is now I need to keep it in a way that it will accept any number of layers. – theJuls Sep 28 '16 at 21:28
1

Is this what your are after: http://codepen.io/PiotrBerebecki/pen/PGjVxW

The solution relies on using React's reusable components. It accepts objects of varying levels of nesting as per your example. You can adjust it further to accommodate even more types of objects.

const stateObject = {
  "3.8": [ "Something something" ], 
  "3.2": [ { "Blabla": [ "More things I am saying", "Blablablabal", "Whatever" ] } ],
  "2.9": [ { "Foo": [ "bar", "something something something something", "blablablabalbalbal" ] } ]
} 


class App extends React.Component {
  render() { 
    const renderMainKeys = Object.keys(stateObject)
      .map(mainKey => <MainKey mainKey={mainKey} 
                      innerObject={stateObject[mainKey]} />);   

    return (
      <div>
        {renderMainKeys}
      </div>
    );
  }
}


class MainKey extends React.Component {
  render() {
    if (typeof this.props.innerObject[0] === 'string') {
      return (
        <div>
          <h4>{this.props.mainKey}</h4>
          <ul>
            <li>{this.props.innerObject[0]}</li>
          </ul>
        </div>
      );
    }

    const innerObjectKey = Object.keys(this.props.innerObject[0])[0];
    const innerList = this.props.innerObject[0][innerObjectKey];

    return (
      <div key={this.props.mainKey}>
        <h4>{this.props.mainKey}</h4>
        <InnerKey innerObjectKey={innerObjectKey} innerList={innerList}/>
      </div>
    )
  }
}

class InnerKey extends React.Component {  
  render() {
    return (
      <ul>
        <li>{this.props.innerObjectKey}</li>
        <InnerList innerList={this.props.innerList} />
      </ul>
    )
  }
}


class InnerList extends React.Component {   
  render() {
    if (!Array.isArray(this.props.innerList)) {
      return (
        <ul>
          <li>{this.props.innerList}</li>
        </ul>
      );
    }

    const listItems = this.props.innerList.map(function(item, index) {
      return <li key={index}>{item}</li>;
    });

    return (
      <ul>
        {listItems}
      </ul>
    );
  }
}


ReactDOM.render(
  <App />,
  document.getElementById('app')
);
Piotr Berebecki
  • 7,428
  • 4
  • 33
  • 42
  • you can achieve this with a lot less code and components wtih a good recursive function – ajmajmajma Sep 29 '16 at 13:40
  • 1
    This worked perfectly! Thank you so much! I will do some clean up to better improve that, but it definitely solved my problem and possibly many future problems! – theJuls Sep 29 '16 at 13:44
  • @ajmajmajma I should have probably asked before, where would be a good place for the recursive function? – theJuls Sep 29 '16 at 15:15
  • @theJuls not sure exactly where to point you, but i crafted one up quickly. I still this this answer is a good one though! But anyways, something like this - https://jsfiddle.net/69z2wepo/58258/ . – ajmajmajma Sep 30 '16 at 04:59