最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React: async and await not working with fetch - Stack Overflow

programmeradmin4浏览0评论

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.

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.

Share Improve this question asked Mar 6, 2021 at 15:29 Mr. EngineerMr. Engineer 3752 gold badges11 silver badges34 bronze badges 5
  • 1 1. You need to return await fetch() 2. getProducts is still going to produce a promise, so you need to consume it as such. Either await it or use getProducts().then() – VLAZ Commented Mar 6, 2021 at 15:31
  • there's also absolutely no need for async/await if it's just a wrapper for a fetch call. function getProducts() { return fetch(...); } – Robin Zigmond Commented Mar 6, 2021 at 15:34
  • Wrap this in useEffect and don’t forget to add any dependencies. Also, I think you shouldn’t use .then with async/await as stated in the answer posted. Use one of the other. – Nathan Hall Commented Mar 6, 2021 at 15:50
  • Alright now JSON is successfully printed to console but I'm getting error "cannot read property map of undefined". It might be better to try to display without map-method? – Mr. Engineer Commented Mar 6, 2021 at 15:59
  • Looks like you are mapping over products directly after setting state. Until the state is set, the products will be undefined. You need to check for that before expecting them to be there. Or, use useEffect. See my example below – Nathan Hall Commented Mar 6, 2021 at 16:15
Add a comment  | 

5 Answers 5

Reset to default 12

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();
},[])

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.

const [data, setData] = useState([]);
    useEffect(() => {
        const fetchAPI = async () => {
            const response = await fetch('http://127.0.0.1:5000/listProducts', {
                method: 'GET',
            }).catch((err) => ('Error', console.error(err)));
            const data = await response.json();
            setData(data);
        };
        fetchAPI();
    }, []);
    return (
        <div className='App'>
            <ul>
                {data.map((items) => (
                    <li key={items.id}>{items.title}</li>
                ))}
            </ul>
        </div>
    );

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>
    </>
  ))


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

发布评论

评论列表(0)

  1. 暂无评论