0

Hello!

I'm using React with React Context API. I have App.js component with whole app. It is functional component. In it' there is state (useState) for context:

const [contextValue, setContextValue] = useState(null)

And useEffect:

useEffect(() => {
    const wrapper = async () => {
      let data = {};

      const fetchData = () => {
        fetchAbout().then((res) => (data.about = res.data));
        fetchNews().then((res) => (data.news = res.data));
        fetchArticles().then((res) => (data.articles = res.data));
        fetchOffer().then((res) => (data.offer = res.data));
        fetchPortfolio().then((res) => (data.portfolio = res.data));
        fetchQuestions().then((res) => (data.questions = res.data));
      };
      await fetchData();

      console.log(data);
      console.log(data.about);

      setContextValue(data);
    };

    wrapper();
  }, []);

So in fetchData function I'm creating properties of data object. So after await fetchData(), there are 2 console logs. And as expected, first is logging data objects with its fields:

data object with it's fields


But there are problem with console.log(data.about);, because it is logging undefined!. I expected, that it'll be value of about field in data object (like in first console.log)

Thanks in advance

  • 1
    Try changing fetchAbout().then((res) => (data.about = res.data.about)); – jarivak Sep 06 '20 at 06:16
  • Your `fetchData` returns `undefined`. You aren't waiting for any of the Promises inside to resolve. Use `Promise.all` to wait for each Promise to resolve first, then call `setContextValue`. `Promise.all([fetchAbout(), fetchNews()]).then((res) => setContextValue({ about: res[0].data, news: res[1].data ...` – CertainPerformance Sep 06 '20 at 06:17

1 Answers1

0

fetchData isn't returning a promise, so you can't "await" for it. by the time you console.log(data.about) the data is not yet populated. you could solve it by

  const fetchData = () => {
    return Promise.all([
       fetchAbout().then((res) => (data.about = res.data)),
       fetchNews().then((res) => (data.news = res.data)),
       fetchArticles().then((res) => (data.articles = res.data)),
       fetchOffer().then((res) => (data.offer = res.data)),
       fetchPortfolio().then((res) => (data.portfolio = res.data)),
       fetchQuestions().then((res) => (data.questions = res.data)),
    ])
  };
naortor
  • 2,019
  • 12
  • 26
  • Thanks so much, it solved my problem. Can you explain, how does `Promise.all()` work? –  Sep 06 '20 at 06:45
  • promise.all gets an array of promises and returns a promise which resolves after all promises have resolved (if one or more failed it will reject) – naortor Sep 06 '20 at 15:47