Mapping over array with deep nested json object - javascript

this is my first post and was extremely confused on how to map over the json data correctly.
The problem comes from when you map the user address property with Object.keys, everything is mapping over fine until it gets to the "geo" property values. What is the solution to map and render over every property easier?
const style = {
list: {
listStyle: "none"
}
};
const data = [
{
id: 1,
name: "Leanne Graham",
username: "Bret",
email: "Sincere#april.biz",
address: {
street: "Kulas Light",
suite: "Apt. 556",
city: "Gwenborough",
zipcode: "92998-3874",
geo: {
lat: "-37.3159",
lng: "81.1496"
}
},
phone: "1-770-736-8031 x56442",
website: "hildegard.org",
company: {
name: "Romaguera-Crona",
catchPhrase: "Multi-layered client-server neural-net",
bs: "harness real-time e-markets"
}
}
];
function App() {
return (
<div className="App">
<ul style={style.list}>
{data.map(user => {
return (
<Fragment key={user.id}>
<li>{user.username}</li>
<ul style={style.list}>
{Object.keys(user.address).map(key => {
return (
<li>
{key} {user.address[key]}
</li>
);
})}
</ul>
</Fragment>
);
})}
</ul>
</div>
);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

Use object keys on geo, in your li check if key is equal to geo, then map over it.
<li>
{key} {key === 'geo' ? Object.keys(user.address[key]).map(geo => <i>{user.address[key][geo]}</i>) : user.address[key] }
</li>
// Get a hook function
const {useState} = React;
const style = {
list: {
listStyle: "none"
}
};
const data = [
{
id: 1,
name: "Leanne Graham",
username: "Bret",
email: "Sincere#april.biz",
address: {
street: "Kulas Light",
suite: "Apt. 556",
city: "Gwenborough",
zipcode: "92998-3874",
geo: {
lat: "-37.3159",
lng: "81.1496"
}
},
phone: "1-770-736-8031 x56442",
website: "hildegard.org",
company: {
name: "Romaguera-Crona",
catchPhrase: "Multi-layered client-server neural-net",
bs: "harness real-time e-markets"
}
}
];
function App() {
return (
<div className="App">
<ul style={style.list}>
{data.map(user => {
return (
<React.Fragment key={user.id}>
<li>{user.username}</li>
<ul style={style.list}>
{Object.keys(user.address).map(key => {
return (
<li>
{key} {key === 'geo' ? Object.keys(user.address[key]).map(geo => <i>{`${geo}: ${user.address[key][geo]} `}</i>) : user.address[key] }
</li>
);
})}
</ul>
</React.Fragment>
);
})}
</ul>
</div>
);
}
// Render it
ReactDOM.render(
<App />,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>

Just add an if statement for geo key and return your desired JSX.
{
Object.keys(user.address).map(key => {
if (key === "geo") {
Object.keys(user.address[key]).map(geoKey => {
return (
<li>
{geoKey} {user.address[key][geoKey]}
</li>
);
});
} else {
return (
<li>
{key} {user.address[key]}
</li>
);
}
});
}

Related

i want to click a button and display a specific component in React

im new to React, so i trying to make a pokemon web app, basically i have a list of data (Data.js) that imported it in another file (PokemonList.js), i mapped that list and rendered all the names in button form, then i want to know how i make every button display that pokemon info ??
Data.js:
export const Data =[
{
id: "1",
name: "arbok",
imageUrl: '../pokemon_images/arbok.png',
desc: "This is Pokemon arbok",
Height : "200 cm",
Weight: "100 kg",
Stat : {
hp : "80",
attack : "82",
defense : "83",
special_attack : "100",
special_defense : "100",
speed : "80",
},
},
{
id: "2",
name: "arcanine",
imageUrl: "",
desc: "This is Pokemon arcanine",
Height : "210 cm",
Weight: "110 kg",
Stat : {
hp : "81",
attack : "83",
defense : "84",
special_attack : "110",
special_defense : "110",
speed : "81",
},
},
PokeList.js
import { Data } from "./Data";
import "./PokeList.css"
import { useState } from "react";
function PokeList() {
const [pokeInfo , setPokeInfo] = useState({
name: "",
desc: ""
})
const handleClick=() => {
setPokeInfo({
})
}
return (
<div className="app-container">
<div className="pokemon-container">
<div className="all-container">
{Data.map((el)=> {
return (
<>
<button onClick={handleClick(el)}> {el.name} </button>
</>
)
}
)}
</div>
</div>
</div>
)
}
export default PokeList;
As you guys can see the code is incomplete and i really have no idea what to do
You'll simply need to do these changes
Change handleClick function to this
const handleClick=(el) => {
setPokeInfo({
name: el.name,
desc: el.desc
})
}
and return function to this
return (
<>
<button onClick={handleClick(el)}> {el.name} {el.desc}</button>
</>
)
This would not 100% map as the answer to your question. But if you share a working JSFiddle with your code - we'll be able to help you out more

React js. Array elements show more show less with useHooks useState

I am kinda fresh to react and useState hooks (still learing).
I want to create show more/less button with use of Array and React hooks.
I came across this code with exact result i want to achieve - showing some part of an array, and then showing the rest/ returning to previous state.
The thing is, the code is written with use of class components. I never even learned them, useState is more recent.
How to achieve something like this, but with use of state hook (useEffect?) if is it possible ?
https://jsbin.com/wowaluwipu/1/edit?html,js,output
class Application extends React.Component {
constructor() {
super()
this.state = {
cars: [
{ "name" : "Audi", "country" : "Germany"},
{ "name" : "BMW", "country" : "Germany" },
{ "name" : "Chevrolet", "country" : "USA" },
{ "name" : "Citroen", "country" : "France" },
{ "name" : "Hyundai", "country" : "South Korea" },
{ "name" : "Mercedes-Benz", "country" : "Germany" },
{ "name" : "Renault", "country" : "France" },
{ "name" : "Seat", "country" : "Spain" },
],
itemsToShow: 3,
expanded: false
}
this.showMore = this.showMore.bind(this);
}
showMore() {
this.state.itemsToShow === 3 ? (
this.setState({ itemsToShow: this.state.cars.length, expanded: true })
) : (
this.setState({ itemsToShow: 3, expanded: false })
)
}
render() {
return <div className="container">
<h3>Click show more to see more data</h3>
<div className="row">
<h3>List of Cars</h3>
<ul>
{this.state.cars.slice(0, this.state.itemsToShow).map((car, i) =>
<li key={i}>{car.name} - {car.country}</li>
)}
</ul>
</div>
Either way, mine works as well as the others. Just in a bit of a different way.
import React, { useState } from 'react'
function Stacks() {
const [itemsToShow, setItemsToShow] = useState(3);
const cars = [
{ "name" : "Audi", "country" : "Germany"},
{ "name" : "BMW", "country" : "Germany" },
{ "name" : "Chevrolet", "country" : "USA" },
{ "name" : "Citroen", "country" : "France" },
{ "name" : "Hyundai", "country" : "South Korea" },
{ "name" : "Mercedes-Benz", "country" : "Germany" },
{ "name" : "Renault", "country" : "France" },
{ "name" : "Seat", "country" : "Spain" },
];
const showmore = () => {
setItemsToShow(cars.length)
}
const showless = () => {
setItemsToShow(3)
}
return (
<div>
{cars.slice(0, itemsToShow).map((car, index) => <li key={index}>{car.name} - {car.country} </li>)}
{(itemsToShow === 3) ? <button onClick={showmore}>Show More</button>: <button onClick={showless}>Show Less</button>}
</div>
)
}
Might not be the efficient way, the only difference is I took out the onliner code from show more and made a separate function show less that resets the original state value which is 3.
I have the same problem when I was just starting in React that I normally see Class Components in tutorials.
hello i had the same problem ,but thanks to help of others it is much clearer
(i cloudnt test if it works myself but that should be it)
import { useState } from "react";
function App() {
// const [state, setstate] = useState(initialState) // this is how it initially is
const [data, setData] = useState({
cars: [
{ name: "Audi", country: "Germany" },
{ name: "BMW", country: "Germany" },
{ name: "Chevrolet", country: "USA" },
{ name: "Citroen", country: "France" },
{ name: "Hyundai", country: "South Korea" },
{ name: "Mercedes-Benz", country: "Germany" },
{ name: "Renault", country: "France" },
{ name: "Seat", country: "Spain" },
],
itemsToShow: 3,
}); // i named it data youcan name it whatever suits you
const showMore = () => {
data.itemsToShow === 3
? // ...data is a spread of the state, that means have all the data and change that
// particular one, in that case "itemsToShow"
setData({ ...data, itemsToShow: data.cars.length })
: setData({ itemsToShow: 3 });
};
return (
<div className="container">
<h3>Click show more to see more data</h3>
<div className="row">
<h3>List of Cars</h3>
<ul>
{data.cars.slice(0, data.itemsToShow).map((car, i) => (
<li key={i}>
{car.name} - {car.country}
</li>
))}
</ul>
</div>
// if the items you want to show are equal to the legth of your car list
then hide the button
{data.itemsToShow < data.cars.length && (
<button onClick={showMore}>Show more</button>
)}
</div>
);
}
export default App;
generally you get rid of ,"this", "this.state", and instead of "this.setState" you put your hook directly like "setNewThings" or "SetCrazyStuff", or what so..
You'll get the hang of it with more practice, hope that helps

How to fetch an array of objects and render it in the component as a normal text using React Hooks?

I want to display some cards information in my app fetching data from an API. Each customer has 1, 2 or 3 different cards, I'm using JWToken for authentication but I have not included it here. So, the API response is not static.
Request: GET "/xx/cards"
Response is an array of objects:
[
{
"cardId": "1",
"cardType": {
"3": "General Card"
},
"salutation": {
"1": "Mrs."
},
"firstName": "Test",
"lastName": "User",
"status": 'active',
"creationDate": "30.10.2020",
},
{
"cardId": "2",
"cardType": {
"2": "Special Card"
},
"salutation": {
"2": "Mr."
},
"firstName": "Test1",
"lastName": "User1",
"status": 'active',
"creationDate": "30.10.2020",
},
]
In The React Context:
const [cards, setCards] = useState<any>([]);
In MyCards.tsx component:
const MyCards: React.FC = () => {
const {
cards,
setCards,
} = React.useContext(AuthContext);
const [content, setContent] = useState([]);
useEffect(() => {
axios.get("/xx/cards").then(
(response) => {
setContent(response.data);
setCards(response.data);
},
(error) => {
const _content =
(error.response && error.response.data) ||
error.message ||
error.toString();
setContent(_content);
}
);
}, []);
return (
<React.Fragment>
<IonPage className="ion-page" id="main-content">
<IonContent className="ion-padding">
<h1>Your Cards</h1>
<p>{JSON.stringify(cards)}</p>
...HERE I should write some code but don't know what...
</IonContent>
</IonPage>
</React.Fragment>
);
};
export default MyCards;
I want to list the cards as a normal text (as following) in my component:
Mrs. Test User
Card Id: 1
Card Type: General Card
Mr. Test1 User1
Card Id: 2
Card Type: Special Card
How to achieve this ? I don't really know how to set state for an array of objects.
Any help would be appreciated. Thanks :)
a solution would be to use the map function on your array see here
return(
...
{
cards.map(card => (
<p>
{card.firstName} {card.lastname}<br/>
Card Id: {card.cardId}<br/>
...
</p>
))
}
...
)
like this but for me there is a probleme in api with is all the key number in object ..
better option for iterate is array of object like this :
[
{
"cardId": "1",
"cardType": "General Card",
"salutation": "Mrs.",
"firstName": "Test",
"lastName": "User",
"status": 'active',
"creationDate": "30.10.2020",
},
...
]
I think what you're looking for is mapping through your array of objects and just displaying them, something like this:
...
<p>{JSON.stringify(cards)}</p>
{cards?.map(card => (
<div>
<p>{Object.values(card.salutation)[0] card.firstName card.lastName}</p>
<p>Card Id: {card.cardId}</p>
<p>Card type: {Object.values(card.cardType)[0]}</p>
</div>
))}
...

Why is my React code rendering multiple elements when I return data?

I am trying to building a React app that returns information about congress when you type in a state in the search box. The only problem is that when it renders, the same information renders multiple times. I know that that when an element renders it will share the same class and it's styling but this is something that I don't know how to fix, as I am new to React. Can some point me in the right direction?
Here is my code:
class Members extends React.Component {
constructor(props) {
super(props);
this.state = {
userInput: null,
senators: [],
represenatives: [],
bills: []
}
}
handleChange = (e) => {
this.setState({
userInput: e.target.value.toUpperCase()
})
}
componentDidMount() {
const urls = [`https://api.propublica.org/congress/v1/116/senate/members.json`,
`https://api.propublica.org/congress/v1/102/house/members.json`,
`https://api.propublica.org/congress/v1/statements/latest.json`,
`https://api.propublica.org/congress/v1/bills/search.json`];
let requests = urls.map(url => fetch(url, {
type: "GET",
dataType: 'json',
headers: {
'X-API-Key': key
}
}))
Promise.all(requests)
.then(res => {
return Promise.all(res.map(res => res.json()));
}).then(response => {
this.setState({
senators: response[0].results[0].members,
represenatives: response[1].results[0].members,
bills: response[2].results
})
console.log(this.state.senators)
}).catch(err => {
console.log(err)
})
}
render() {
const { senators, bills, represenatives, userInput } = this.state;
const inSenate = senators.filter(
(senator) => senator.state === userInput
)
const inHouse = represenatives.filter(
(represenative) => represenative.state === userInput
)
const draft = bills.find(
(bill) => bill.name === inSenate.last_name)
return (
<div className="congress">
<div className="users">
<h2>{this.state.userInput}</h2>
<input className="userInput" onChange={this.handleChange} />
</div>
{inSenate.map((senate, i) => {
return (
<div key={inSenate.id} className="senate">
<h2 key={inSenate.id} className="senateName">Senate</h2>
<ul key={inSenate.id} className="bio">
<h2 key={inSenate.id}>{senate.short_title + " " + senate.first_name + " " + senate.last_name}</h2>
<li key={inSenate.id}>{senate.title}</li>
<li key={inSenate.id}>State: <strong>{senate.state}</strong></li>
<li key={inSenate.id}>Party: <strong>{senate.party}</strong></li>
<li key={inSenate.id}>DOB: <strong>{senate.date_of_birth}</strong></li>
<li key={inSenate.id}>Next Election: <strong>{senate.next_election}</strong></li>
<li key={inSenate.id}>Missed Votes: <strong>{senate.missed_votes}</strong></li>
<li key={inSenate.id}> Votes With Party Percentage: <strong>{senate.votes_with_party_pct + "%"}</strong></li>
<li key={inSenate.id}>Votes Against Party Percentage: <strong>{senate.votes_against_party_pct + "%"}</strong></li>
</ul>
</div>
)
})}
{inHouse.map((rep, i) => {
return (
<div key={inHouse.id} className="houses">
<h2 className="numbers" key={inHouse.id}>Your state has {inHouse.length} Represenative(s)</h2> // this renders multiple times as what is in the length
<div className="house">
<h2 key={inHouse.id}>{rep.short_title + " " + rep.first_name + " " + rep.last_name}</h2>
<ul key={inHouse.id} className="bio">
<li key={inHouse.id}>{rep.title}</li>
<li key={inHouse.id}>State: <strong>{rep.state}</strong></li>
<li key={inHouse.id}>Party: <strong>{rep.party}</strong></li>
<li key={inHouse.id}>DOB: <strong>{rep.date_of_birth}</strong></li>
<li key={inHouse.id}>Next Election: <strong>{rep.next_election}</strong></li>
<li key={inHouse.id}>Missed Votes: <strong>{rep.missed_votes}</strong></li>
<li key={inHouse.id}> Votes With Party Percentage: <strong>{rep.votes_with_party_pct + "%"}</strong></li>
<li key={inHouse.id}>Votes Against Party Percentage: <strong>{rep.votes_against_party_pct + "%"}</strong></li>
</ul>
</div>
</div>
)
})}
</div>
)
}
}
[1]: https://i.stack.imgur.com/8121x.jpg
You need to move repetitive <h2> out of map() function:
return (
<div className="congress">
<div className="users">
<h2>{this.state.userInput}</h2>
<input className="userInput" onChange={this.handleChange} />
</div>
{/* inSenate.map() */}
<h2 className="numbers" key={inHouse.id}>Your state has {inHouse.length} Represenative(s)</h2>
{/* inHouse.map() */}
</div>
)
Try fully working example below:
class Members extends React.Component {
constructor(props) {
super(props);
this.state = {
userInput: null,
senators: [],
represenatives: [],
bills: []
};
}
handleChange = e => {
this.setState({
userInput: e.target.value.toUpperCase()
});
};
// needed to simplify function code to make it runnable
// responseData is `members` array (source: https://projects.propublica.org/api-docs/congress-api/members/)
componentDidMount() {
this.setState({
represenatives: responseData
});
}
render() {
const inHouse = this.state.represenatives.filter(
item => item.state === this.state.userInput
);
return (
<div className="congress">
<div className="users">
<h2>{this.state.userInput}</h2>
<input className="userInput" onChange={this.handleChange} />
<span>Write "TN" or "WY"</span>
</div>
<h2 className="numbers">
Your state has {inHouse.length} Represenative(s)
</h2>
{inHouse.map((rep, i) => {
return (
<div key={inHouse.id} className="houses">
<div className="house">
<h2>
{rep.short_title + " " + rep.first_name + " " + rep.last_name}
</h2>
<ul className="bio">
<li>{rep.title}</li>
<li>
State: <strong>{rep.state}</strong>
</li>
<li>
Party: <strong>{rep.party}</strong>
</li>
<li>
DOB: <strong>{rep.date_of_birth}</strong>
</li>
<li>
Next Election: <strong>{rep.next_election}</strong>
</li>
<li>
Missed Votes: <strong>{rep.missed_votes}</strong>
</li>
<li>
{" "}
Votes With Party Percentage:{" "}
<strong>{rep.votes_with_party_pct + "%"}</strong>
</li>
<li>
Votes Against Party Percentage:{" "}
<strong>{rep.votes_against_party_pct + "%"}</strong>
</li>
</ul>
</div>
</div>
);
})}
</div>
);
}
}
const responseData = [
{
id: "A000360",
title: "Senator, 2nd Class",
short_title: "Sen.",
api_uri:
"https://api.propublica.org/congress/v1/members/A000360.json",
first_name: "Lamar",
middle_name: null,
last_name: "Alexander",
suffix: null,
date_of_birth: "1940-07-03",
gender: "M",
party: "R",
leadership_role: null,
twitter_account: "SenAlexander",
facebook_account: "senatorlamaralexander",
youtube_account: "lamaralexander",
govtrack_id: "300002",
cspan_id: "5",
votesmart_id: "15691",
icpsr_id: "40304",
crp_id: "N00009888",
google_entity_id: "/m/01rbs3",
fec_candidate_id: "S2TN00058",
url: "https://www.alexander.senate.gov/public",
rss_url: "https://www.alexander.senate.gov/public/?a=RSS.Feed",
contact_form:
"http://www.alexander.senate.gov/public/index.cfm?p=Email",
in_office: true,
cook_pvi: null,
dw_nominate: 0.324,
ideal_point: null,
seniority: "17",
next_election: "2020",
total_votes: 374,
missed_votes: 75,
total_present: 0,
last_updated: "2019-12-04 07:18:43 -0500",
ocd_id: "ocd-division/country:us/state:tn",
office: "455 Dirksen Senate Office Building",
phone: "202-224-4944",
fax: "202-228-3398",
state: "TN",
senate_class: "2",
state_rank: "senior",
lis_id: "S289",
missed_votes_pct: 20.05,
votes_with_party_pct: 96.98,
votes_against_party_pct: 3.02
},
{
id: "E000285",
title: "Senator, 2nd Class",
short_title: "Sen.",
api_uri:
"https://api.propublica.org/congress/v1/members/E000285.json",
first_name: "Michael",
middle_name: "B.",
last_name: "Enzi",
suffix: null,
date_of_birth: "1944-02-01",
gender: "M",
party: "R",
leadership_role: "",
twitter_account: "SenatorEnzi",
facebook_account: "mikeenzi",
youtube_account: "senatorenzi",
govtrack_id: "300041",
cspan_id: "45824",
votesmart_id: "558",
icpsr_id: "49706",
crp_id: "N00006249",
google_entity_id: "/m/021ph1",
fec_candidate_id: "S6WY00126",
url: "https://www.enzi.senate.gov",
rss_url: "https://www.enzi.senate.gov/public/?a=rss.feed",
contact_form:
"http://www.enzi.senate.gov/public/index.cfm/contact?p=e-mail-senator-enzi",
in_office: true,
cook_pvi: null,
dw_nominate: 0.542,
ideal_point: null,
seniority: "23",
next_election: "2020",
total_votes: 374,
missed_votes: 2,
total_present: 0,
last_updated: "2019-12-03 19:50:32 -0500",
ocd_id: "ocd-division/country:us/state:wy",
office: "379a Russell Senate Office Building",
phone: "202-224-3424",
fax: "202-228-0359",
state: "WY",
senate_class: "2",
state_rank: "senior",
lis_id: "S254",
missed_votes_pct: 0.53,
votes_with_party_pct: 96.76,
votes_against_party_pct: 3.24
},
{
id: "B001261",
title: "Senator, 1st Class",
short_title: "Sen.",
api_uri:
"https://api.propublica.org/congress/v1/members/B001261.json",
first_name: "John",
middle_name: null,
last_name: "Barrasso",
suffix: null,
date_of_birth: "1952-07-21",
gender: "M",
party: "R",
leadership_role: "Senate Republican Conference Chair",
twitter_account: "SenJohnBarrasso",
facebook_account: "johnbarrasso",
youtube_account: "barrassowyo",
govtrack_id: "412251",
cspan_id: "1024777",
votesmart_id: "52662",
icpsr_id: "40707",
crp_id: "N00006236",
google_entity_id: "/m/02rsm32",
fec_candidate_id: "S6WY00068",
url: "https://www.barrasso.senate.gov",
rss_url: "https://www.barrasso.senate.gov/public/?a=rss.feed",
contact_form:
"https://www.barrasso.senate.gov/public/index.cfm/contact-form",
in_office: true,
cook_pvi: null,
dw_nominate: 0.538,
ideal_point: null,
seniority: "13",
next_election: "2024",
total_votes: 374,
missed_votes: 0,
total_present: 0,
last_updated: "2019-12-03 19:50:32 -0500",
ocd_id: "ocd-division/country:us/state:wy",
office: "307 Dirksen Senate Office Building",
phone: "202-224-6441",
fax: null,
state: "WY",
senate_class: "1",
state_rank: "junior",
lis_id: "S317",
missed_votes_pct: 0.0,
votes_with_party_pct: 96.77,
votes_against_party_pct: 3.23
}
];
ReactDOM.render(<Members />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

cannot get data from object Uncaught TypeError: Cannot read property 'street' of undefined

i have a json data like this :
"results": [
{
"gender": "male",
"name": {
"title": "mr",
"first": "romain",
"last": "hoogmoed"
},
"location": {
"street": "1861 jan pieterszoon coenstraat",
"city": "maasdriel",
"state": "zeeland",
"postcode": 69217
},
"email": "romain.hoogmoed#example.com",
"login": {
"username": "lazyduck408",
"password": "jokers",
"salt": "UGtRFz4N",
"md5": "6d83a8c084731ee73eb5f9398b923183",
"sha1": "cb21097d8c430f2716538e365447910d90476f6e",
"sha256": "5a9b09c86195b8d8b01ee219d7d9794e2abb6641a2351850c49c309f1fc204a0"
},
"dob": "1983-07-14 07:29:45",
"registered": "2010-09-24 02:10:42",
"phone": "(656)-976-4980",
"cell": "(065)-247-9303",
"id": {
"name": "BSN",
"value": "04242023"
},
"picture": {
"large": "https://randomuser.me/api/portraits/men/83.jpg",
"medium": "https://randomuser.me/api/portraits/med/men/83.jpg",
"thumbnail": "https://randomuser.me/api/portraits/thumb/men/83.jpg"
},
"nat": "NL"
}
],
"info": {
"seed": "2da87e9305069f1d",
"results": 1,
"page": 1,
"version": "1.1"
}
}
i made it to get data object from Axios ,
when i console.log(this.state.contact.location) , it displayed location object
{street: "2868 avenida de andalucía", city: "gandía", state: "región de murcia", postcode: 43796}
but when i tried console.log(this.state.contact.location.street)
i get error
Uncaught TypeError: Cannot read property 'street' of undefined
here's my code :
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
import React, { Component } from 'react';
import AppBar from 'material-ui/AppBar';
import Drawer from 'material-ui/Drawer';
import MenuItem from 'material-ui/MenuItem';
import axios from 'axios';
import {
Table,
TableBody,
TableHeader,
TableHeaderColumn,
TableRow,
TableRowColumn
} from 'material-ui/Table';
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
open: false,
contact: []
}
}
componentDidMount() {
axios.get('https://randomuser.me/api/')
.then((result) => {
this.setState({
contact: result.data.results[0]
})
})
.catch(function (error) {
console.log(error);
})
}
handleToggle = () => this.setState({ open: !this.state.open });
handleClose = () => this.setState({ open: false });
render() {
console.log(this.state.contact.location)
//console.log(this.state.contact.location.city) i can't use this
return (
<div className="App">
<AppBar
title="My App"
iconClassNameRight="muidocs-icon-navigation-expand-more"
onLeftIconButtonTouchTap={this.handleToggle}
/>
<Drawer
docked={false}
open={this.state.open}
onRequestChange={(open) => this.setState({ open })}>
<MenuItem onClick={this.handleClose}>Contact List</MenuItem>
<MenuItem onClick={this.handleClose}>To-Do List</MenuItem>
</Drawer>
<Table>
<TableHeader displaySelectAll={false} adjustForCheckbox={false}>
<TableRow>
<TableHeaderColumn >No</TableHeaderColumn>
<TableHeaderColumn >Name</TableHeaderColumn>
<TableHeaderColumn >Gender</TableHeaderColumn>
<TableHeaderColumn >Email</TableHeaderColumn>
<TableHeaderColumn >Phone</TableHeaderColumn>
</TableRow>
</TableHeader>
{/* <TableBody displayRowCheckbox={false}>
<TableRow>
<TableRowColumn>{1}</TableRowColumn>
<TableRowColumn>{this.state.contact.name.first}</TableRowColumn>
<TableRowColumn>{this.state.contact.gender}</TableRowColumn>
<TableRowColumn>{this.state.contact.email}</TableRowColumn>
<TableRowColumn>{this.state.contact.phone}</TableRowColumn>
</TableRow>
</TableBody> */}
</Table>
</div>
)
}
}
Your code is good. The reason of the error is the console.log itself.
console.log(this.state.contact.location)
console.log(this.state.contact.location.city)
In the first mount, your state.contact is an empty array so that state.contact.location return undefined and state.contact.location.city give you your error. After fetching data from axios your data should be there correctly

Categories

Resources