Having done the necessary to read the data using fetchAPI, I am having problems displaying the content because of the nature of the array.
import React, { useState, useEffect } from "react";
function Home() {
const [userData, setUserData] = useState([]);
async function getData() {
let response = await fetch("https://api.xxxxxxxx.io/something/students");
let data = await response.json();
return data;
}
//call getData function
getData().then((data) => console.log(data)); //
useEffect(() => {
getData()
.then((data) => {
setUserData(data);
})
.catch((error) => {
console.log(error);
});
}, []);
return (
<div>
{Object.keys(userData).map((item, index) => (
<div key={index}>{item}</div>
))}
</div>
);
}
export default Home;
When I checked the console, the data are displayed but it is only showing students with no other data displayed.
I have the data below.
Try the following changes:
const [userData, setUserData] = useState({ students: [] });
...
return (
<div>
{userData.students.map((item, index) => (
<div key={index}>{item}</div>
))}
</div>
);
Related
This is my code to show the get request data in frontend
import React, { useEffect, useState } from "react";
import axios from "axios";
const Users = () => {
const [users, setusers] = useState({ collection: [] });
const [Error, setError] = useState();
useEffect(() => {
axios
.get("http://127.0.0.1:5000/users/users-list")
.then((response) => {
console.log(response.data);
// console.log(response.status);
// console.log(response.statusText);
// console.log(response.headers);
// console.log(response.config);
setusers({ collection: response.data });
return response.data;
})
.catch((error) => {
console.log({ Error: error });
setError(error);
// return error;
});
}, []);
return (
<div>
{users.collection.length > 0 &&
users.collection.map((element, i) => {
return (
<div key={i}>
{element.Name}‑{element.Email}
‑{element.Message}
</div>
);
})}
{Error && <h2>{Error}</h2>}
</div>
);
};
export default Users;
As you can see in the following code I am trying to display my get data in the browser web page .
but its is not displaying in the browser but showing in console.log()
First of all dont make variable starts with capital letter as you have used Error (which refers to Error class in JavaScript) in useState.
You can show component with different state as follows:
const [isLoading, setIsLoading] = useState(false);
const [users, setUsers] = useState([]);
const [error, setError] = useState("");
useEffect(() => {
setIsLoading(true);
axios.get("http://127.0.0.1:5000/users/users-list")
.then((res => {
setUsers(res.data);
setIsLoading(false);
})
.catch(err => {
setError(err.response.data);
setIsLoading(false);
}
},[]);
if (isLoading) {
return <LoadingComponent />
}
if (error !== "") {
return <h1>{error}</h1>
}
if (users.length < 1) {
return <h1>There is no user.</h1>
}
return <div>
{users.collection.map((element, i) => {
return (
<div key={i}>
{element.Name}‑{element.Email}
‑{element.Message}
</div>
);
})}
</div>
You implementation ok it's work with [{"Name":"T","Email":"t#email.com","Message":"T user"}] API response format. Just check what is API response in your end, It should render the results.
I have notice catch block you have to set error message instead of Err object
import React, { useEffect, useState } from 'react';
import axios from 'axios';
const Users = () => {
const [users, setusers] = useState({ collection: [] });
const [Error, setError] = useState('');
useEffect(() => {
axios
.get('https://63a0075424d74f9fe82c476c.mockapi.io/api/collection/Test')
.then((response) => {
console.log(response.data);
// console.log(response.status);
// console.log(response.statusText);
// console.log(response.headers);
// console.log(response.config);
setusers({ collection: response.data });
})
.catch((error) => {
console.log({ Error: error });
setError('Something went wrong');
// return error;
});
}, []);
return (
<div>
{users.collection.length > 0 &&
users.collection.map((element, i) => {
return (
<div key={i}>
{element.Name}‑{element.Email}
‑{element.Message}
</div>
);
})}
{Error && <h2>{Error}</h2>}
</div>
);
};
export default Users;
<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>
I tested your code (with a different API) and could not find any issues. As you can see in the codesandbox, the values appear on the screen:
https://codesandbox.io/s/wonderful-ganguly-5ecbid?file=/src/App.js
I noticed that you capitalised the object properties, Name, Email and Message. Perhaps this caused you the issue. You will need to check the console logged object to see whether the properties are capitalised or not. Usually, they will not be. So you would call them like this: element.name, element.email and element.message.
I guess your response data is maybe your problem. I don't know what is your response but it must be array.
I have replace the axios url with some other fake urls and it worked. but remember that the user.collection must be array. Therefor, you need to make sure that response.data is array. Otherwise, you need to set response.data as array in user.collection.
import React, { useEffect, useState } from "react";
import axios from "axios";
const Users = () => {
const [users, setusers] = useState({ collection: [] });
const [Error, setError] = useState();
useEffect(() => {
axios
.get("https://jsonplaceholder.typicode.com/todos/1")
.then((response) => {
console.log(response.data);
setusers({ collection: [response.data] });
return response.data;
})
.catch((error) => {
console.log({ Error: error });
setError(error);
// return error;
});
}, []);
return (
<div>
{users.collection.length > 0 &&
users.collection.map((element, i) => {
return <div key={i}>{element.title}</div>;
})}
{Error && <h2>{Error}</h2>}
</div>
);
};
export default Users;
I want to display the response from my fetch request in react. So far, I built the fetch request and set up the useEffect and useState hooks. The response is an object. What am I doing wrong?
function App() {
const url = 'https://api.gemini.com/v1/book/btcusd'
const [orders, setOrders] = useState([])
const fetchData = () => {
fetch(url).then(response => {
return response.json();
}).then(data => {
console.log(data)
setOrders(data)
}).catch(error => {
console.log(error)
})
}
useEffect(() => {
fetchData()
}, [])
return (
<div className="App">
<h1>{orders.asks}</h1>
</div>
);
}
export default App;
Taking a quick look at that API, the asks property holds an array of objects. You would need to map those to JSX elements in order to display them.
Also, if orders is meant to be an object, you should not initialise it as an array.
Finally, you should always check the Response.ok property to see if the request resolved successfully.
// fetch-data.js
const url = "https://api.gemini.com/v1/book/btcusd";
export const fetchData = async () => {
const res = await fetch(url);
if (!res.ok) {
throw Object.assign(new Error(`${res.status}: ${res.statusText}`), {
url,
text: await res.text(),
});
}
return res.json();
};
// App.jsx
import { useEffect, useState } from "react";
import { fetchData } from "./fetch-data";
function App() {
// init with an object with empty `asks` array
const [orders, setOrders] = useState({ asks: [] });
useEffect(() => {
fetchData().then(setOrders).catch(console.error);
}, []);
return (
<div className="App">
{/* Map over the data */}
{orders.asks.map(({ price, amount }, i) => (
<dl key={i}>
<dt>Price</dt>
<dd>{price}</dd>
<dt>Amount</dt>
<dd>{amount}</dd>
</dl>
))}
</div>
);
}
export default App;
Your data is an object. You should use map to loop.
const url = "https://api.gemini.com/v1/book/btcusd";
const [orders, setOrders] = useState({ asks: [{price: 0, amount: 0}], bids: [{price: 0, amount: 0}] });
const fetchData = () => {
fetch(url)
.then((response) => {
return response.json();
})
.then((data) => {
console.log(data); //Data: {bids: Array(50), asks: Array(50)}
setOrders(data);
})
.catch((error) => {
console.log(error);
});
};
useEffect(() => {
fetchData();
}, []);
return (
<div className="App">
<table className="table">
<thead>
<th>Ask price</th>
<th>Ask amount</th>
<th>Bid price</th>
<th>Bid amount</th>
</thead>
{orders.asks?.map((e, i) => {
return (
<>
<tr>
<td>{e.price}</td>
<td>{e.amount}</td>
<td>{orders.bids[i].price}</td>
<td>{orders.bids[i].amount}</td>
</tr>
</>
)
})}
</table>
</div>
);
You Can use map function to display each item
eg:
orders.asks.map(item=>
<div>
<h1>{item.price}</h1>
<h1>{item.amount}</h1>
</div>
)
I'm practising React with a small project where I want to display some Nba players but I don't get any data when trying to map an object.
I'm using this Api: http://data.nba.net/prod/v1/2022/players.json
Here is the code:
import React, { useEffect, useState } from "react";
const Players = () => {
const url = "http://data.nba.net/prod/v1/2022/players.json";
const [players, setPlayers] = useState([]);
useEffect(() => {
getPlayers();
}, []);
const getPlayers = async () => {
const api = await fetch(url);
const data = await api.json();
//wrapping a object into a array
setPlayers([data].flat());
};
return (
<div>
<h3>Sacramento player info</h3>
<ul>
{players.map((player) => (
<li key={player.league.sacramento.id}>
{player.league.sacramento.firstName}{" "}
{player.league.sacramento.lastName}{" "}
</li>
))}
</ul>
</div>
);
};
export default Players;
I recreated your code on codesandbox and it works just fine. I use other approach on getting data thru fetch and changed http:// to https://
const Players = () => {
const [data, setData] = useState(null);
function getAPIData() {
fetch("https://data.nba.net/prod/v1/2022/players.json")
.then((response) => {
if (response.ok) {
return response.json();
}
throw new Error("ERROR (response not ok)");
})
.then((data) => {
setData(data);
})
.catch((response) => {
console.log("error");
});
}
useEffect(() => getAPIData(), []);
return (
data && (
<div>
<h3>Sacramento player info</h3>
<ol>
{data.league.sacramento.map((player) => (
<li key={player.personId}>
{player.firstName} {player.lastName}
</li>
))}
</ol>
</div>
)
);
};
working code: https://codesandbox.io/s/players-info-51gf1w
function App() {
const [todos, setTodos] = useState(null);
useEffect(() => {
const GetTodos = async () => {
try {
const { data } = await axios.get("api/orders");
console.log(data);
setTodos(data);
console.log(todos);
} catch (err) {
console.log(err);
}
};
GetTodos();
}, []);
return (
<div className="App">
<h1>hello</h1>
{todos?.map((todo) => (
<p key={todo.ID}>{todo.ID}</p>
))}
</div>
);
}
How can I make the data I got from the API display on the page, I can see that it works when I log it to the console but it doesn't show up on the page
Okay the problem is your data returns an Array of Arrays.
Because your data has just one array nested inside, we can just use it as the data hook, something like this:
setTodos(data[0]);
to understand, here is an example
You could do as below, calling setTodos(data[0]) in your try-catch, as your API seems to be returning an array with the data you want at position 0.
function App() {
const [todos, setTodos] = useState(null);
useEffect(() => {
const GetTodos = async () => {
try {
const { data } = await axios.get("api/orders");
console.log(data);
setTodos(data[0]);
} catch (err) {
console.log(err);
}
};
GetTodos();
}, []);
return (
<div className="App">
<h1>hello</h1>
{todos && todos.map((todo) => (
<p key={todo.ID}>{todo.ID}</p>
))}
</div>
);
}
I have problem with load data to component after click on button.
I use getInitialProps to first load data on page.
How to load new data and past them to {data} after click?
export default function Users({ data }) {
const fetchData = async () => {
const req = await fetch("https://randomuser.me/api/?gender=male&results=100");
const data = await req.json();
return { data: data.results };
};
const handleClick = (event) => {
event.preventDefault();
fetchData();
};
return (
<Layout>
<button onClick={handleClick}>FETCH DATA</button>
{data.map((user) => {
return (
<div>
{user.email}
<img src={user.picture.medium} alt="" />
</div>
);
})}
</Layout>
);
}
Users.getInitialProps = async () => {
const req = await fetch(
"https://randomuser.me/api/?gender=female&results=10"
);
const data = await req.json();
return { data: data.results };
};
Thank a lot for help!
Use useState with the default value being the data you initially retrieved via getInitialProps:
import { useState } from 'React';
export default function Users({ initialData }) {
const [data, setData] = useState(initialData);
const fetchData = async () => {
const req = await fetch('https://randomuser.me/api/?gender=male&results=100');
const newData = await req.json();
return setData(newData.results);
};
const handleClick = (event) => {
event.preventDefault();
fetchData();
};
return (
<Layout>
<button onClick={handleClick}>FETCH DATA</button>
{data.map((user) => {
return (
<div>
{user.email}
<img src={user.picture.medium} alt="" />
</div>
);
})}
</Layout>
);
}
Users.getInitialProps = async () => {
const req = await fetch('https://randomuser.me/api/?gender=female&results=10');
const data = await req.json();
return { initialData: data.results };
};
Sidenote: Times have changed and it would seem that user1665355 is indeed correct:
Recommended: getStaticProps or getServerSideProps
If you're using Next.js 9.3 or newer, we recommend that you use
getStaticProps or getServerSideProps instead of getInitialProps.
These new data fetching methods allow you to have a granular choice
between static generation and server-side rendering.
import { useState } from 'React';
export default function Users({ initialData }) {
const [data, setData] = useState(initialData);
const fetchData = async () => {
const req = await fetch('https://randomuser.me/api/?gender=male&results=100');
const newData = await req.json();
setData(newData.results);
};
const handleClick = (event) => {
event.preventDefault();
fetchData();
};
return (
<Layout>
<button onClick={handleClick}>FETCH DATA</button>
{data.map(user => {
return (
<div key={user.login.uuid}>
{user.email}
<img src={user.picture.medium} alt="" />
</div>
);
})}
</Layout>
);
}
Users.getInitialProps = async () => {
const req = await fetch('https://randomuser.me/api/?gender=female&results=10');
const data = await req.json();
return { initialData: data.results };
};
I would like to list my notes about George's code. At least, it should pay attention to them.
First of all, it should attach any key to a div element otherwise a warning will have appeared in the browser console. Here is an article about using keys: https://reactjs.org/docs/lists-and-keys.html#keys
As well, the keyword return can be removed from the fetchData function that doesn't return a response.
It is recommended to use getStaticProps or getServerSideProps now. https://nextjs.org/docs/api-reference/data-fetching/getInitialProps