Reputation: 333
I am attempting to map a large amount of data in React with which Iv'e had a decent amount of success with. Now i'm attempting to retrieve data from a nested JSON object and I have no idea how to. My JSON data is below.
{
"core-topics": [
{
"id": "coding",
"name": "Coding",
"headerColour": "blue",
"description": "Learn how to build your very own website!",
"image": "https://www.bitdegree.org/tutorials/wp-content/uploads/2018/08/what-is-a-web-developer.jpg",
"link": [
{
"id": "coding-item-one",
"name": "Java"
},
{
"id": "coding-item-two",
"name": "C++"
},
{
"id": "coding-item-three",
"name": "Python"
}
]
},
I'm accessing this data using a method that searches for a specific component id and then returns the matching data.
const Writer = ({match: {url}, coreTopics}) => {
return (
<React.Fragment>
/* This renders each link from the JSON file */
/* And maps it onto the card layout component below */
<Route path = {`${url}/:topicId`} render = {
/* searches for a matching id and renders all properties if it finds a match */
({ match }) =>
<card {...coreTopics.find(topic => topic.id === match.params.topicId)}/>}/>
</React.Fragment>
)
}
While using a template component to render all of the JSON data to a HTML format.
class card extends React.Component {
constructor(props){
super(props);
this.state = {
links: {}
}
}
render(){
return(
<Container>
<HeaderImage headerImage = {this.props.image}>
<ImageTextContainer>
<H1> {this.props.name} </H1>
<Stripe stripeColour = {this.props.headerColour}/>
<P> {this.props.description} </P>
</ImageTextContainer>
/* What I'm attempting to do with 0 luck. */
/* I am also aware the code isn't correct, i'm just demonstrating my logic behind this. */
<ul>
{this.props.link.map((name, id)) =>
<li id = {link.id}> {link.name} </li>
})
</ul>
</HeaderImage>
</Container>
)
}
}
Each time I try to access the properties within the link object, I get an error saying that the map function cannot be used on undefined. It is basically impossible to get any data out of this object and I have no idea why. I can access all of the data easily except any nested objects.
Any help at all is appreciated! I understand this is quite a large post and probably includes too much information but I couldn't think of another way to get this all across to anyone who might be able to help.
Upvotes: 0
Views: 266
Reputation: 8125
Update the Card component to take data using prop key, do not spread it.
class Card extends React.Component {
constructor(props){
super(props);
this.state = {
links: {}
}
}
render(){
const card = this.props.card || {link: []}
return(
<Container>
<HeaderImage headerImage = {card.image}>
<ImageTextContainer>
<H1> {card.name} </H1>
<Stripe stripeColour = {card.headerColour}/>
<P> {card.description} </P>
</ImageTextContainer>
</HeaderImage>
</Container>
)
}
}
Pass data using key(prop)
const Writer = ({match: {url}, coreTopics}) => {
const card = coreTopics.find(topic => topic.id === match.params.topicId)
return (
<React.Fragment>
<Route path = {`${url}/:topicId`} render = {
({ match }) =>
<card card={card}/>}/>
</React.Fragment>
)
}
Upvotes: 1
Reputation: 872
In your question, it isn't clear where or how you are passing in the JSON object you listed. But for an example, if I had this object, and wanted to write a function that would return a matching topic... I would write something like this:
const coreTopicsJson = {
"core-topics": [
{
"id": "coding",
"name": "Coding",
"headerColour": "blue",
"description": "Learn how to build your very own website!",
"image": "https://www.bitdegree.org/tutorials/wp-content/uploads/2018/08/what-is-a-web-developer.jpg",
"link": [
{
"id": "coding-item-one",
"name": "Java"
},
{
"id": "coding-item-two",
"name": "C++"
},
{
"id": "coding-item-three",
"name": "Python"
}
]
}
]
}
const findTopicById = (topicId, coreTopicsJson) => (
coreTopicsJson["core-topics"].find(({id}) => id === topicId)
)
const codingCoreTopic = findTopicById("coding", coreTopicsJson) // returns object of topic with id of 'coding'
Perhaps this might help on how to pull data from the JSON object?
Upvotes: 1