Updating (and accessing) state while fetching APIs

Hey all, so I’m trying to fetch quotes for the Random Quote Generator and I can pull in the quotes and seemingly save them to state AND print them to the console, however, whenever I try to get them print on the browser…it doesn’t work.

Here’s the error I consistently get:

** Invariant Violation: Objects are not valid as a React child (found: object with keys {quote, author}). If you meant to render a collection of children, use an array instead. **

But I thought I WAS using an array (that has objects in it?)?

Any help is MUCH appreciated as I’m pulling my hair out over this:


class QuoteApp extends React.Component {
  constructor() {
      super()
      this.state = {
        info: [],
        key: 0
    };

  }
 componentDidMount() {
        fetch("https://gist.githubusercontent.com/camperbot/5a022b72e96c4c9585c32bf6a75f62d9/raw/e3c6895ce42069f0ee7e991229064f167fe8ccdc/quotes.json")
            .then(response => response.json())
            .then(results => {
                const updatedInfo = results.quotes
                this.setState({
                    info: updatedInfo
                })
            })
            .catch(err => console.log(err));      
    }

  
  render() {
   
    return (
      <div id="wrapper">
      <p> {this.state.info}</p>
      </div>
    );
  }
}

export default QuoteApp
      const newId = <ChangeQuote handleSubmit={this.handleSubmit}/>

What is that doing there? and what is it returning ? , You want all your components that render something to be inside the return statement of your render function

In your handleSubmit function, put a console log to see what updateId is.

handleSubmit() {
        const updatedId = getRandomId(this.state.info.length + 1)
        //this.componentDidMount()
        console.log(updateId)
        this.setState({
            key: updatedId
        })
    }

it may not be what you are expecting

This is just linking handlesubmit that creates a button to call handlesubmit and change the key value. I just didn’t want all my html on the same page so I’m in the process of breaking it down in parts. The ChangeQuote code looks like this:

import React from "react"

function ChangeQuote(props) {
    return(
        <div>
            <button
                type="submit"
                onClick={() => props.handleSubmit()}>
                Quote
            </button>
        </div>
    )
}

export default ChangeQuote

it prints a number like I hoped it does. Am I missing something?

I see, sorry I didn’t pay attention that you were calling the returned jsx in your render function, anyway , your problem is that you have misplaced parentheses in your fetch, see below

        fetch("https://gist.githubusercontent.com/camperbot/5a022b72e96c4c9585c32bf6a75f62d9/raw/e3c6895ce42069f0ee7e991229064f167fe8ccdc/quotes.json")
            .then(response => response.json())
            .then(results => {
                const updatedInfo = results.quotes
                this.setState({
                    info: updatedInfo
                })
             }) <--- And add it here
            .catch(err => console.log(err));
            }) <--- Remove this

of course I don’t know what getRandomId does either, but your state should be set with the data once you fix above

can you post a codepen?

I haven’t been working in codepen, but I migrated it over and I still can’t figure it out.

I am unable to load the json data into state (at least from the api) and then print to the browser. Ready to throw my computer through the window.

https://codepen.io/tmacmcgraw/full/NJVvwM

Could a be a problem between the fact i’m using fetch and already retrieving a .json file?

do this in componentDidMount

 this.setState({
      info: data.quotes
  })

and render this in your <p> tags

<p>{JSON.stringify(this.state.info[0])}</p>

You can’t just render an object or an array as is.

Have a look at this. I printed all the quotes to the console, and printed one the the page.

I used a for in loop to iterate over the quotes object
https://www.w3schools.com/jsref/jsref_forin.asp

Try work off this and let us know if you have any more questions

1 Like

I have no idea if what you did is the best solution, but it WORKED. I BOW DOWN TO THEE. You have saved me from buying a new computer. Thank you so much!

No problem, and I bet it is not even close to the best solution :sweat_smile:
Still quite a lot of work to do to finish the project but at least you can read, access, and print some quotes.

1 Like