NewGuyHere
NewGuyHere

Reputation: 15

React fetch API won't return the result

I'm having trouble trying to fetch API from this API https://gutendex.com/books/.

This is my code:

import {useState, useEffect} from 'react'

export default function App() {
  const [data, setData] = useState([])
  const LoadData = async() =>{
    const value = await fetch('https://gutendex.com/books/');
    const res = await value.json()
    setData(res.results[0])

  }

  useEffect(() =>{
    LoadData()
  },[])


  return (
    <div className="App">
       <img src={data.formats.image/jpeg} alt={data.title}/>
    </div>
  );
}

The error it shows:

data.formats is undefined

Then I try the return{data.formats} to see what happen. It shows new error like this

Error Objects are not valid as a React child (found: object with keys {application/x-mobipocket-ebook, application/epub+zip, application/rdf+xml, text/html; charset=utf-8, text/plain; charset=utf-8, image/jpeg, text/html}). If you meant to render a collection of children, use an array instead.

Can someone tell me what is wrong?

Upvotes: 0

Views: 604

Answers (2)

Wayne Celestin
Wayne Celestin

Reputation: 159

You could maybe rearrange your function a bit. Instead of writing the function apart, write it in the useEffect. I know gunwin already gave the answer, but I am concentrating on the useEffect function. So here is the solution:

useEffect(() => {
  const loadData = async () => {
     await fetch('https://gutendex.com/books/')
     .then((res) => res.json())
     .then((data) => setData(data.results[0]))
     .catch((err) => console.error(err))
  }
}, []);

This should normally work, if not check this: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch

Upvotes: 1

gunwin
gunwin

Reputation: 4832

The image is rendered before the API call is complete. When this happens there is no data to display. Change you return statement to this:

 return (
    <div className="App">
       {data && (<img src={data.formats["image/jpeg"]} alt={data.title}/>)}
    </div>
  );

Also, the initial value of data shouldn't be an array, you should set this to null or undefined.

The image will be hidden until the API call is complete, and data

Upvotes: 3

Related Questions