Been banging my ahead against a wall on this one for a while. Doing the FCC course, essentially completed a project but trying to fetch a JSON with an array rather than just putting one in directly, myself, as I wanted to learn how to do it… Didn’t think it would be this difficult!
What do I want to do?
I want to fetch a json and assign the array within it to state within my react component. I’ll then use a random num gen to pick a random quote to display from the array.
Where am I having trouble?
I’m able to fetch the json and log the quotes to the console, however whenever I try to assign them to a variable, I end up with the promise object. I think it’s a problem that I must’ve misunderstood/not quite wrapped my head around asynchronous functions yet
What I need help with
I’ve created a new codepen, separate to the task, where I have been testing how to get this to work without React, so I can then work it into my React project when I know what to do.
I’m able to log the first quote in the array to the console when I run the async function, however when I try to use that same async function to return that quote to myQuote, it returns a Pending Promise. Am I approaching this correctly at all, or am I completely going in the wrong direction?
If you don’t want to visit the codepen link, code below:
const testFetch = fetch('https://gist.githubusercontent.com/camperbot/5a022b72e96c4c9585c32bf6a75f62d9/raw/e3c6895ce42069f0ee7e991229064f167fe8ccdc/quotes.json') .then(response => response.json()) .then((quote) => { return quote.quotes; }) // The console.log below logs "The quote is [quote as a string]" to the console const testVar = async () => { const quoteArr = await testFetch; console.log("The quote is ", quoteArr[0].quote); return quoteArr[0].quote; }; let myQuote = testVar(); // This logs "Is my quote variable working? [Promise pending]" to the console console.log("Is my quote variable working? + ", myQuote)
Advertisement
Answer
A common pattern in react (although not the best one) is to call fetch in useEffect and set the state in .then.
The simplest example would be
import React, { useEffect, useState } from "react"; const App = () => { const [quotes, setQuotes] = useState<any>([]); useEffect(() => { fetch( "https://gist.githubusercontent.com/camperbot/5a022b72e96c4c9585c32bf6a75f62d9/raw/e3c6895ce42069f0ee7e991229064f167fe8ccdc/quotes.json" ) .then((response) => response.json()) .then((quote) => { setQuotes(quote.quotes); }); }, [setQuotes]); return ( <div> {quotes.length > 0 && quotes.map((quote: any) => <div>{quote.quote}</div>)} </div> ); }; export default App;
A modern alternative in React is to use ReactQuery for fetching data, as it provides nice abstractions and caching out of the box.