I am a beginner in writing React applications. Please help me where I have gone wrong in writing the code. This is the API- https://api.coindesk.com/v1/bpi/currentprice.json. I am not able to iterate over the json format that I have received from fetch function. Below is the code.
//import logo from './logo.svg';
import './App.css';
import {useEffect, useState} from 'react';
function App() {
const[bitData, setbitData]=useState([]);
useEffect(()=>{
fetch("https://api.coindesk.com/v1/bpi/currentprice.json",{
method:'GET'
}).then(result=>result.json())
.then(result=>setbitData(result))
},[])
return (
<div className="App">
{ bitData &&
<table className="table">
<thead>
<tr>
<th scope="col">Code</th>
<th scope="col">Symbol</th>
<th scope="col">Rate</th>
<th scope="col">Description</th>
<th scope="col">Rate_float</th>
</tr>
</thead>
<tbody>
{
bitData.map(draw=>
<tr>
<th scope="row">{draw.code}</th>
<td>{draw.symbol}</td>
<td>{draw.rate}</td>
<td>{draw.description}</td>
</tr>
)}
</tbody>
</table>
}
</div>
);
}
export default App;
This is the error:
Uncaught TypeError: bitData.map is not a function
at App (App.js:28:1)
at renderWithHooks (react-dom.development.js:16305:1)
at updateFunctionComponent (react-dom.development.js:19588:1)
at beginWork (react-dom.development.js:21601:1)
at beginWork$1 (react-dom.development.js:27426:1)
at performUnitOfWork (react-dom.development.js:26557:1)
at workLoopSync (react-dom.development.js:26466:1)
at renderRootSync (react-dom.development.js:26434:1)
at recoverFromConcurrentError (react-dom.development.js:25850:1)
at performConcurrentWorkOnRoot (react-dom.development.js:25750:1)
App @ App.js:28
renderWithHooks @ react-dom.development.js:16305
updateFunctionComponent @ react-dom.development.js:19588
beginWork @ react-dom.development.js:21601
beginWork$1 @ react-dom.development.js:27426
performUnitOfWork @ react-dom.development.js:26557
workLoopSync @ react-dom.development.js:26466
renderRootSync @ react-dom.development.js:26434
recoverFromConcurrentError @ react-dom.development.js:25850
performConcurrentWorkOnRoot @ react-dom.development.js:25750
workLoop @ scheduler.development.js:266
flushWork @ scheduler.development.js:239
performWorkUntilDeadline @ scheduler.development.js:533
CodePudding user response:
The api link you are using returns a json response (JavaScript Object), which doesn't have '.map()'. This function is used for arrays.
From your code and the json provided by the API I believe you are trying to reach the elements under the 'bpi'.
I edited the last .then in your fetch request so you get an array in bitData instead of an object:
fetch("https://api.coindesk.com/v1/bpi/currentprice.json",{
method:'GET'
}).then(result=>result.json())
.then(result=>setbitData(Object.values(result.bpi)))
CodePudding user response:
The issue is bitData
is a JSON object. you can use Object.values() to get the actual values in it.
Try like below:
const App = () => {
const [bitData, setbitData] = React.useState(null);
React.useEffect(() => {
fetch("https://api.coindesk.com/v1/bpi/currentprice.json", {
method: "GET"
})
.then((result) => result.json())
.then((result) => setbitData(result));
}, []);
return (
<div className="App">
{bitData && (
<table className="table">
<thead>
<tr>
<th scope="col">Code</th>
<th scope="col">Symbol</th>
<th scope="col">Rate</th>
<th scope="col">Description</th>
<th scope="col">Rate_float</th>
</tr>
</thead>
<tbody>
{bitData &&
Object.values(bitData.bpi).map(
({ code, symbol, rate, description, rate_float }) => (
<tr key={code}>
<th scope="row">{code}</th>
<td>{symbol}</td>
<td>{rate}</td>
<td>{description}</td>
<td>{rate_float}</td>
</tr>
)
)}
</tbody>
</table>
)}
</div>
);
}
ReactDOM.render(<App />, document.querySelector('.react'));
table,
td,
th {
border: 1px solid;
padding: 5px;
}
table {
border-collapse: collapse;
}
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div class='react'></div>