daveyholler
daveyholler

Reputation: 141

React - Accessing nested objects in returned data

I'm using fetch to return some data from a local API. I'm able to return the data and set the state. However, in my render() function when using map and attempting to access anything deeper than the top level object in the data I get an undefined error. I can correctly log any level of the data that I want to the console, but I don't have access to it within the rendered component.

constructor(props) {
  super(props);
  this.state ={
    verifications: []
  }
}

componentWillMount(){
  fetch('http://localhost:3001/verifications')
    .then(response => response.json())
    .then((verifications) => {
      this.setState({verifications})
      console.log(this.state);
    });
}

and in my render

{this.state.verifications.map(verification =>
  <div key={verification._id}>
    <ReviewListItem
      hasAvatar={true}
      imageUrl={verification.supplier.logo}
      title={verification.supplier.companyName}
      description={verification.tasks.length}
    />
  </div>
)}

This is the error I get: Unhandled Rejection (TypeError): Cannot read property 'logo' of null

I've searched high and low for an answer to this, but I feel like I must be approaching this wrong. I come from Angular 1, and I'm extremely new to React. Maybe I'm having a hard time grasping the concepts.

Here's my data:

[
{
"_id": 1000,
"supplier": {
"_id": 1000,
"companyName": "ACME Business Ventures",
"logo": "/images/logos/suppliers/acme.jpg",
"avettaId": "ADS83J",
"brandColor": "#563E5E",
"clients": [],
"locations": [],
"primaryContact": {},
"address": {},
"createdAt": "2017-06-30T17:42:23.479Z"
},
"tasks": [
{
"form": "PQF General",
"question": "How long have you been in business?",
"answer": "18 Years",
"status": "incomplete",
"attachment": "",
"comments": []
},
{
"form": "PQF General",
"question": "Have you had any fatalities in the last 3 years?",
"answer": "No",
"status": "incomplete",
"attachment": "",
"comments": []
},
{
"form": "Diversity Questionnaire",
"question": "Are you a minority-owned business?",
"answer": "Yes",
"status": "incomplete",
"attachment": "",
"comments": []
},
{
"form": "Sustainability Questionnaire",
"question": "What percentage of your business runs on renewable energy?",
"answer": "About 55%, but that's expected to climb to 80% by next year.",
"status": "incomplete",
"attachment": "",
"comments": []
}
]
},
{
"_id": 2000,
"supplier": null,
"tasks": [
{
"form": "PQF General",
"question": "How long have you been in business?",
"answer": "18 Years",
"status": "incomplete",
"attachment": "",
"comments": []
},
{
"form": "PQF General",
"question": "Have you had any fatalities in the last 3 years?",
"answer": "No",
"status": "incomplete",
"attachment": "",
"comments": []
},
{
"form": "Diversity Questionnaire",
"question": "Are you a minority-owned business?",
"answer": "Yes",
"status": "incomplete",
"attachment": "",
"comments": []
},
{
"form": "Sustainability Questionnaire",
"question": "What percentage of your business runs on renewable energy?",
"answer": "About 55%, but that's expected to climb to 80% by next year.",
"status": "incomplete",
"attachment": "",
"comments": []
}
]
},
{
"_id": 3000,
"supplier": null,
"tasks": [
{
"form": "PQF General",
"question": "How long have you been in business?",
"answer": "18 Years",
"status": "incomplete",
"attachment": "",
"comments": []
},
{
"form": "PQF General",
"question": "Have you had any fatalities in the last 3 years?",
"answer": "No",
"status": "incomplete",
"attachment": "",
"comments": []
},
{
"form": "Diversity Questionnaire",
"question": "Are you a minority-owned business?",
"answer": "Yes",
"status": "incomplete",
"attachment": "",
"comments": []
},
{
"form": "Sustainability Questionnaire",
"question": "What percentage of your business runs on renewable energy?",
"answer": "About 55%, but that's expected to climb to 80% by next year.",
"status": "incomplete",
"attachment": "",
"comments": []
}
]
},
{
"_id": 4000,
"supplier": null,
"tasks": [
{
"form": "PQF General",
"question": "How long have you been in business?",
"answer": "18 Years",
"status": "incomplete",
"attachment": "",
"comments": []
},
{
"form": "PQF General",
"question": "Have you had any fatalities in the last 3 years?",
"answer": "No",
"status": "incomplete",
"attachment": "",
"comments": []
},
{
"form": "Diversity Questionnaire",
"question": "Are you a minority-owned business?",
"answer": "Yes",
"status": "incomplete",
"attachment": "",
"comments": []
},
{
"form": "Sustainability Questionnaire",
"question": "What percentage of your business runs on renewable energy?",
"answer": "About 55%, but that's expected to climb to 80% by next year.",
"status": "incomplete",
"attachment": "",
"comments": []
}
]
}
]

Upvotes: 2

Views: 3715

Answers (3)

Dmitry Sokurenko
Dmitry Sokurenko

Reputation: 6132

The supplier is clearly null in your json snippet:

"supplier": null,

Thus it obviously fails :)

I believe angular automatically checks for nulls in expressions like this: foo.bar.baz.something.deeply.nested — so if anything is null the result will be null — in react, (and in js in general)‚ you need to check for nulls by yourself.

Upvotes: 2

pizzarob
pizzarob

Reputation: 12049

The second index of your array has supplier: null. You can check that supplier exists first

{this.state.verifications.map(verification =>
  <div key={verification._id}>
    <ReviewListItem
      hasAvatar={true}
      imageUrl={verification.supplier && verification.supplier.logo}
      title={verification.supplier && verification.supplier.companyName}
      description={verification.tasks.length}
    />
  </div>
)}

Upvotes: 2

Sassan
Sassan

Reputation: 2337

One of your suppliers is null (at least one). Consider using something like imageUrl={verification.supplier ? verification.supplier.logo : null} instead of imageUrl={verification.supplier.logo}.

Upvotes: 5

Related Questions