Random quote machine API error

Tell us what’s happening:
when i console.log(this.state.quotes[3]) it gives me the properties

{
quote: 'some quote',
author: 'author_name'
}

but when i do console.log(this.state.quotes[3].quote) kit gives mw error saying
Cannot read property ‘quote’ of undefined
at App.render (pen.js:24)

i really dont know what happening here.

Your code so far

        const API = 'https://gist.githubusercontent.com/camperbot/5a022b72e96c4c9585c32bf6a75f62d9/raw/e3c6895ce42069f0ee7e991229064f167fe8ccdc/quotes.json'

class App extends React.Component {
  constructor(props){
    super(props)
    this.state = {
      quotes: [],
      index: 0
    }
  }
  
  componentDidMount() {
    fetch(API).then(res => res.json())
      .then(res => {
        this.setState({
          quotes: res.quotes
        });
    });
  }
  
  
  render() {
    console.log(this.state.quotes[3].quote)
    
    return (
      <h1>hello</h1>
    )
  }
}

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/87.0.4280.88 Safari/537.36.

Challenge: Build a Random Quote Machine

Link to the challenge:

code error so far

using console.log() in the render method can lead to trouble when dealing with asynchronous processes. You can try a simple verification in your console.log():

console.log(this.state.quotes[3] ? this.state.quotes[3].quote : "Sorry")

now i am getting sorry and in next line getting the quote

That means that the console.log() in the render method is getting called before componentDidMount() and then once again after the component mounts.

Check out the React docs here for order of execution.

From the docs:

These methods are called in the following order when an instance of a component is being created and inserted into the DOM:

I’ve edited your post for readability. When you enter a code block into a forum post, please precede it with a separate line of three backticks and follow it with a separate line of three backticks to make it easier to read.

You can also use the “preformatted text” tool in the editor (</>) to add backticks around text.

See this post to find the backtick on your keyboard.
Note: Backticks (`) are not single quotes (’).

1 Like

so how can i get the quotes… i can see the quote and author but i cannot access it.

You said console.log() was executed twice, right?

So, you are getting the quote. When you set up the quote to be displayed as text in an html element, use a conditional.

{this.state.something && <p>{this.state.something.property}</p>}

my actual issue is on line 24 and 26.


as you can see in the console i get the object with quote and author as properties from line 24.
but it doesnt work from line 26

What happens when you do

console.log(this.state.quotes[1] && this.state.quotes[1].quote)

?

Sure.
The render() method is called before componentDidMount(), so your console.log() is executed once before the functions in componentDidMount() are invoked. At this point, this.state.quotes is an empty array. So, console.log(this.state.quotes[1].quote) should throw an error because this.state.quotes = []. After componentDidMount() finishes, the render() method gets called again because state was updated when your component mounted. Since your console.log() is in the render method, it gets executed again. Using the logical && operator makes it so that your code only executes if a condition is met, protecting you from an error.

Oh now it makes sense. Thanks alot :blush: :blush: :blush:

1 Like