React: async and await not working with fetch

Viewed 11820

I have API on Node server returning JSON like this when called:

{"result":[{"ProductID":1,"ProductName":"iPhone10","ProductDescription":"Latest smartphone from Apple","ProductQuantity":100}]}

I'm trying to display all of that information to user using fetch API with React but no matter what my call returns undefined. Here is my React code:

const [products, setProducts] = useState({})

async function getProducts() {
    await fetch(`http://127.0.0.1:5000/listProducts`)
    .then(response => response.json())
    .then(response=>{
      setProducts({products:response.result})
      console.log(response.result);
      products.map(products =>
        <h1>{products.ProductName}</h1>
        <h1>{products.ProductDescription}</h1>
        )
    })
    .catch(err=>console.error(err))
  }

Function getProducts() is called once when page is loaded. What I'm doing wrong? Thanks in advance.

4 Answers

Your function is doing it wrong :

  • The name should be getAndSetProducts or even setProducts / initProducts because it returns a Promise<void> since you don't actually return anything ;
  • You're setting inside products an object { products: Product[] }, I think you want only Product[] (an array of Products) else you'll have to get products by doing products.products ;
  • The map is useless, since you don't do anything with the map response, plus the variable products in the map overwrite the one imported (may cause some errors later).

Try to do :

const [products, setProducts] = useState([]); // Array instead of object

async function initProducts() {
    await fetch(`http://127.0.0.1:5000/listProducts`)
        .then(response => response.json())
        .then(response => {
            setProducts(response.result);
            console.log(response.result);
        )
        .catch(err => console.error(err));
}

function getProductsHtml() {
    return products.map(product =>
        <h1>{product.ProductName}</h1>
        <h1>{product.ProductDescription}</h1>
    );
}

You can call initProducts when component initialize and return getProductsHtml inside your jsx render.

Try this...


 const [products, setProducts] = useState({})

  React.useEffect(() => {
    const fetchData = async () => {
      const result = await fetch('http://127.0.0.1:5000/listProducts')

        // console log here to determine how to set products
      console.log(result)
      setProducts(result)
    }

    fetchData()
  }, [])

  React.useEffect(() => {
   if (!!products) {
     // here you could access products!
    }
  }, [products])

  if (!products) return null

  return products.map((product) => (
    <>
      <h1>{products.ProductName}</h1>
      <h1>{products.ProductDescription}</h1>
    </>
  ))


Try this it will work

const handleFetchData = async () => {
    const response = await fetch(`https://api.unsplash.com/photos/random?client_id=${process.env.NEXT_PUBLIC_UNSPLASH_API_ACCESS_KEY}`);
    const data = await response.json();
    console.log(data);
}

useEffect(() => {
    handleFetchData();
},[])

you can't use async await with .then() you should only use async await or .then() only

Related