Home > Back-end >  React / JS - Fetch() - Assigning resulting array to a variable I can use
React / JS - Fetch() - Assigning resulting array to a variable I can use

Time:10-29

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)

CodePudding user response:

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.

CodePudding user response:

In react, you need to load data after the render into the state. You can not just globally fetch and get data correctly. The below code will clarify.

const testFetch = fetch('https://gist.githubusercontent.com/camperbot/5a022b72e96c4c9585c32bf6a75f62d9/raw/e3c6895ce42069f0ee7e991229064f167fe8ccdc/quotes.json')
    .then(response => response.json())
    .then((quote) => {
    return quote.quotes;
})

const MyComponent = () => {
  useEffect(()=>{
     testFetch.then(quoteArr => {
      console.log('The quote is ', quoteArr[0].quote);
    });
  },[])
}

CodePudding user response:

This syntax is equivalent to the async/await syntax in that it is resolving the promise. It's a redundancy using both.

const testFetch = fetch('https://gist.githubusercontent.com/camperbot/5a022b72e96c4c9585c32bf6a75f62d9/raw/e3c6895ce42069f0ee7e991229064f167fe8ccdc/quotes.json')
    .then(response => response.json())
    .then((quote) => {
    return quote.quotes;
})

You can try something like this

// you must also use react state to save your data
const [state, setState] = useState()

const testFetch = async () => {
  // with this syntax you need to wrap it in a try/catch to catch your errors
  try {
      // res here is equivalent to [response] above
      const res = await fetch('https://gist.githubusercontent.com/camperbot/5a022b72e96c4c9585c32bf6a75f62d9/raw/e3c6895ce42069f0ee7e991229064f167fe8ccdc/quotes.json')
      console.log(res)
      return res
    } catch (err) {
      console.log(err)
      return
    }
  }

// and called upon component mount using useeffect
useEffect(() => {
  const testVar = testFetch()
  setState(testVar)
}, [])
  • Related