I’ve asked a similar question here before but I still can’t figure this out.
I have a React project where I’m retrieving JSON data from an API. The API is returning an Object with other Objects nested with in. I am able to programatically iterate through the outer object but I can’t for the life of me figure out how to access the nested object.
An object with other objects nested within it. I want to access the properties within the nested object named content . If I open it it looks like this:
How would I grab the content from each property within this content object i.e. binanceexchange/binance-labs-ask-us-anything, and nairadaddy/good-person-token-something and so on and so forth?
Note that current_route is a property of the outer object and I am able to access this via dot notation i.e. data.current_route
The current_route property I am able to access and properly display because it is not an object. If I try to access content or any of the objects I get an error.
CAn you share the exact code you tried that didn’t work? Could be a simple typo or syntax error. I also have a lot of nested and nested objects and arrays, and I use the method I posted to grab whatever level I need.
do you know the names of these properties ahead of time? (like you know the name of ‘content’ or is that what you’re trying to solve?
Object keys should do that , then you need to use dot notation to get the value from the content.thisKey, which is again another object.
Can you port this to a codepen pen or provide a github link? I understand your question but would hve to play with the syntax to get it working just right.
What I want to do is grab posts from within the content objects. The posts will vary and will always have different names so it’s not something I can just hard code.
And here you go. The code invovled is in the MyPosts component:
I’ve already done that, but it looks a little different because i pulled out the content when defining the data. I changed the names to make it easier for me to think about the structure and purpose. I think in a case like this, “posts” is much better than “data”, because there are nested and nested levels of “data”.
So yes, you’re right what you’ve done pulls out the name of each post, but you need to dive into each one and pull out it’s content, and that’s what I have done in my sandbox.
There has to be a much, much easier way to do this. I am able to console.log the nested object, content, why can’t I just pass the nested object to Object.keys and iterate over it like so:
render() {
// Logs data
console.log(this.state.myPosts);
const data = this.state.myPosts;
// Stores nested object I want to access in posts variable
const posts = data.content;
// Successfully logs nested object I want to access
console.log(posts);
// Error, this will not allow me to pass posts variable to Object.keys
const display = Object.keys(posts).map(key =>
<option value={key}>{posts[key]}</option>
)
return(
<div>
{display}
</div>
);
I get an error TypeError: can't convert undefined to object error when I try to pass posts to Object.keys
The API data is called in a componentDidMount function. Is this what is causing posts to be undefined? The component hasn’t successfully retrieved the posts variable’s data before trying to use it in the render function and this causes it to be undefined?
The behavior of console.log has nothing to do with React. It is illegal to pass an object as a child of a component.
If dumping all the values in a nested object is what you want, then you can convert it to nested array and pass that directly.
Also, you are probably right about why you are getting that error. So, try giving a default state that is fail safe.
What if I set the state to the nested object content to begin with and then use Object.keys to iterate through it? Pretty sure I have the logic down but I can’t figure out the syntax:
import React, { Component } from 'react';
import dsteem from 'dsteem';
import { Client } from 'dsteem';
class MyPosts extends Component {
constructor(props) {
super(props);
this.state = {
myPosts: [],
nestedObject: []
}
}
componentDidMount() {
const client = new Client('https://api.steemit.com')
client.database
.getState('@ned')
.then(result => {
// Old way I've been trying
this.setState({ myPosts: result });
// Set nestedObject to the object I want
this.setState({ nestedObject: result.content});
})
}
render() {
//console.log(this.state.myPosts);
//const data = this.state.myPosts;
//const posts = data.content;
const posts = this.state.nestedObject;
//console.log(posts);
// Somehow use something like this to iterare through nested object
const display = Object.keys(posts).map(key =>
<option value={key}>{posts[key]}</option>
)
return(
<div>
{/*display*/}
</div>
);
}
}
export default MyPosts;
Object.keys(o) only returns the outer most keys of an object. So, calling it once will never solve the problem of passing object as a child of a react component.
For example
const person = {
name: {
first: "John",
last: "Doe"
},
age: 15,
secret: {
secret2: {
secret3: {
val: "I ate your cookie"
}
}
}
}
const keys = Object.keys(person) // [name, age, secret]
// person[name] => object, illegal to pass as child
// person[age] => number, can pass as child
// person[secret] => object
So, if the data has 3 levels of nested objects, you need to call Object.keys() at least three times to iterate over all the value.
If you really need to display the whole nested object, then you have to use a function like the one that I’ve wrote in previous post, to convert each primitive data into some React component. And pass that as an array.
For example
let data= []
visit(obj, (val) => {
data.push(<p>{val}</p>) // wraps any non-object type inside <p>
})
...
return <SomeComponent> {data} </SomeComponent>
But honestly, I don’t know why you want to iterate over the whole nested object. Why do you need to do this?