Build a Random Quote Machine With React

Tell us what’s happening:
Currently trying to figure out why I “Cannot read property 'author of undefined” when I console.log ‘theData’ and it shows ‘author’ as one of the properties

Your code so far

 const { useState, useEffect } = React

function App() {
  const [theData,setTheData] = useState([])
  const [randomQuote,setRandomQuote] = useState('')
  const [randomAuthor,setRandomAuthor] = useState("")
  
  const API = "https://gist.githubusercontent.com/camperbot/5a022b72e96c4c9585c32bf6a75f62d9/raw/e3c6895ce42069f0ee7e991229064f167fe8ccdc/quotes.json"
  
  useEffect(()=>{
      fetch(API)
      .then(res => res.json())
      .then(data => setTheData(data.quotes))
  },[])
  
  console.log(theData[10]) // **but not here**
  
  console.log(theData[10].author) // **issue here**

return(
    <div></div>
)    

ReactDOM.render(<App/>,document.getElementById('app'));

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36.

Challenge: Build a Random Quote Machine

Link to the challenge:
https://www.freecodecamp.org/learn/front-end-libraries/front-end-libraries-projects/build-a-random-quote-machine

1 Like

I’ve edited the original post to make it more readable. Specifically, I added three backticks before the code block and three backticks after.

You can post code in two ways. Single word/line snippets can be handled inline. Multiple lines should be handled in code blocks:

Inline

Wrap your code in a single back ticks:

Example:

Code Blocks

Wrap your code in triple back ticks, with new lines between the back ticks and code:

Example:

Typing Backticks:arrow_heading_up:

QWERTY and QWERTZ (Key that’s been marked with red border)

When I reproduce the full log for console.log(theData[10]) is:

undefined
{your object}

It implies that the code is executed twice. I think that’s the way states work, but not sure at all.

undefined is due to theData being an empty array [ ], and then is run after the set, so it prints a value. I’ve tested this in node, defining an empty array and trying to access emptyArray[10] is undefined.

Then if the previous idea is correct theData[15].value won’t find an object, and it returns error the first time you call it.

I don’t know how you could fix this…

  • useEffect() runs after the initial render
  • During the initial render, theData is an empty array and theData[10] is undefined
  • You’re trying to access the author property of an undefined array element during the initial render, which leads to an error

Here’s what the React docs have to say about doing things like logging in the main body of a function component:

Mutations, subscriptions, timers, logging, and other side effects are not allowed inside the main body of a function component (referred to as React’s render phase ). Doing so will lead to confusing bugs and inconsistencies in the UI.
https://reactjs.org/docs/hooks-reference.html#useeffect

Though, to avoid the error, you could just replace:

console.log(theData[10].author)

with

console.log(theData[10] ? theData[10].author : "nothing here yet")
1 Like