1

I'm new to using Axios so I figured I would use it with React to make a small PWA just for fun and to learn it. The function is simple press button info get's displayed. When I'm trying to display the info in the return() i get an error saying it can't read the property of the api endpoint so I think what is happening is it's trying to render it before the function is being called. I assume this is a good use for async / await but I'm not sure how to implement it.

Here is the code

const IndexPage = () => {
  const [data, getData] = useState([])

  const options = {
    method: 'GET',
    url: 'https://dad-jokes.p.rapidapi.com/random/joke',
    headers: {
      'X-RapidAPI-Host': 'dad-jokes.p.rapidapi.com',
      'X-RapidAPI-Key': '17fb7de893msh59a82cece7f697ap1c0305jsn0e7db5ca2d76'
    }
  };
  
    function jokes() {
      axios.request(options).then((res) =>  {
      console.log(res.data);
      const data =  res.data
      getData(data)
    }).catch((error) => {
      console.error(error);
    });
  }

  return (
    <Layout>
      <main className="full-page">
        <div className="center">
          <cite>Press for the best dad jokes around!</cite>
          <button onClick={jokes}> Get Jokes</button>

          <h4>{data.body[0].setup}</h4> // this is running before function is being called onClick.
          <p>{data.body[0].punchline}</p> 
        </div>
      </main>
    </Layout>
  );
};

thank you in advance!

6
  • Why is your setData() function called getData()? Second time I've seen it this week. Is there a tutorial out there that's telling people to do this? React docs clearly call this a setter. The "get" is when you read the value. Commented Mar 25, 2022 at 22:03
  • Can you show the word-for-word error? Are you sure it's not complaining that body doesn't exist? Commented Mar 25, 2022 at 22:05
  • No, no tutorial I followed or anything I just saw some examples on line when trying to solve my issue and saw it. Commented Mar 25, 2022 at 22:05
  • Would you mind linking the example? Commented Mar 25, 2022 at 22:05
  • sure I can look for it! Also the error just says cannot read properties of undefined then points to the h4. I think it's because the data from the axios request isn't called until the button is clicked so there is no {data.body[0].setup} yet to be referenced. Commented Mar 25, 2022 at 22:08

1 Answer 1

1
  const [data, getData] = useState([])   

Should be called setData. See https://reactjs.org/docs/hooks-state.html

On first run, data is set to [], an empty array. Later on,

   <h4>{data.body[0].setup}</h4>

You try to read body[0].setup from the array. This line is equivalent to [].body[0].setup.

You can use the optional chaining operator (?.) here:

   <h4>{data?.body?.[0]?.setup}</h4>

Which will evaluate to undefined instead of complaining "can't read property of undefined".

Sign up to request clarification or add additional context in comments.

4 Comments

This worked perfectly so is this the correct way for it to be handled or is my code just off so this is a work around?
@Brandon.b this is one way of doing it. A more general solution is to have another state called isLoading. If isLoading, then display a spinner or just nothing. If not isLoading, the data should all be ready, so just display everything. It depends on your needs, in this case this solution is fine but if we had to decide whether or not to load a component, the other solution might be easier.
Thank you I really appreciate thee answer and the information you've provided you rock. so if I went the isLoading solution then it would be a basic if statement then would the if statemeent wrap the function how would it know to differentiate between when isLoading finishes and then displays the result?
haha no worries, glad I could help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.