1

I'm very new to Javascript and React, so please excuse if this is a dumb question...I'm calling data from an API that gives me a json made up of a bunch of objects within objects within objects. I'm trying to create a nested menu of all of these objects, but I'm having trouble even rendering each level.

I've tried using Object.keys to turn the first layer of objects' items into an array, but it won't let me return these results (only console.log works) because I get the "Objects are not valid as a React child" error for the objects within. How do I access these 4-5 layer-deep objects without having super messy code?

Please let me know if you want to see more code/the json objects laid out or any screenshots

componentDidMount() {
    axios
      .get("https://www.ifixit.com/api/2.0/categories")
      .then(response => this.setState({ categories: response.data }));
  } 

listOfCategories returns an array of the first layer of objects

  render() {
    const { categories } = this.state;
    const listOfCategories = Object.keys(categories);
    console.log(listOfCategories);

this is the part where I can do console.log(categories[key]) and see the second layer to the last layer of nested objects, but I can't actually return it because of the "Objects are not valid as a React child" error.

    const list = listOfCategories.map(key => {
      console.log(categories[key]);
      //return categories[key];
      return null;
    });

this part actually renders the first layer of categories to the screen

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

Screenshot of console.log(categories[key]), which shows the data starting from the second layer of objects. The first layer (listOfCategories) is: Apparel {}, Appliance{}, Camera{}, Car and Truck{}, etc.

enter image description here

7
  • How does console.log(categories[key]); look like? Commented May 3, 2019 at 17:07
  • @HasanSh I just added a screenshot! Commented May 3, 2019 at 17:11
  • I see, and must say this structure isn't simple so great you're dealing with it. You should do the same as you're doing for the categories object(e.g. const category = Object.keys(categories[key]); return category.map(c => c['someProperty']);). Let me know if that's clear! Commented May 3, 2019 at 17:15
  • I think I've tried this way as well and it tells me that [key] is undefined, since it is out of the scope of const list...also, because the json data I'm trying to use is 15 objects with each of those having another 8-10 objects, and more objects within those, do you know if there is a way I can recursively call something to just apply it to each level? Commented May 3, 2019 at 17:21
  • 1
    here is an example codesandbox.io/embed/v600z3mwn7 Commented May 3, 2019 at 17:26

2 Answers 2

1

You should return a React element.

Also, refer to how Render Multiple Components.

Your code should look something like this:

class Categories extends Component  {

state = { categories: [] };

componentDidMount() {
    axios
      .get("https://www.ifixit.com/api/2.0/categories")
      .then(response => this.setState({ categories: response.data }));
  } 

  render() {
    const { categories } = this.state;
    const categoriesKeys = categories.keys().map(key => {
      // Create your submenu
      console.log(categories[key]);

      // Return react element
      // Your key should be unique (avoid using array index)
      return <SubMenu key={unique(key)}>{JSON.stringify(categories[key])}</SubMenu>;
    });


    return <Menu>{categoriesKeys}</Menu>;
  }
Sign up to request clarification or add additional context in comments.

5 Comments

When I do this I still get the same "Objects are not valid as a React child (found: object with keys" error for each layer of objects I have... :(
It won't let me do it this way because it's not going through an array of objects, but an object of objects
I think Dennis didn't realize that categories[key] is an object as well!
@HasanSh Well she only added it now, thanks for the downvote
@Emily answer edited, added JSON.stringify(categories[key]), anyway, you should handle the rest from this example, refer to links.
0

I was facing similar issues, when I tried to view a nested object from MongoDB. Assuming you (or any person viewing this) are using asynchronous function to obtain data what gets returned is Nested Objects. Due to its nature you are not sure what will be the final result from the server. Instead of using JSON.stringify you may opt for just outputting the sub items in the following format within the outer MAP

                  categories.map((key) =>   
                          <span className="" key={key._id}>
                        <b>{key.Apparel ? key.Apparel.SOMEPROPERTY : 'Nothing' }</b>
                          </span>   
                    )

Notice that checking is important because otherwise it throws the error, you mentioned. That approach is not to be used with deeply nested objects.

Comments

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.