0

I am struggle to make a multiple times fetch in useEffect. for understand I got to 2 Collection in my mongoDB.

the backend works, I test the request and I do go the data, so my problem is in the frontend.

because I am using async function the first function doesn't finish to get the data that is necessary to the second fetch data, that issue give me an error that the value is undefined (if I type the static id and not the loadedState everything work)

the code:

  const [loadedContent, setLoadedContent] = useState();
  const [loadedSectors, setLoadedSectors] = useState();

  useEffect(() => {
    const fetchContent = async () => {
      try {
        //get the first document (we need the web id)
        const responseData = await sendRequest(
          process.env.REACT_APP_BACKEND_URL + "/maincontent/"
        );
        responseData.content.forEach((content, index) => {
          content.serial = index + 1; //add serial number (1,2,3...)
        });
        setLoadedContent(responseData.content);
      } catch (err) {}
    };

    const fetchSectors = async () => {
    //get the second document that depend on the web id = loadedContent[0].id
      try {
        const responseData = await sendRequest(
          process.env.REACT_APP_BACKEND_URL +
            "/sector/" +
            loadedContent[0].id +
            "/AllSectors"
        );
        responseData.sectors.forEach((sector, index) => {
          sector.serial = index + 1; //add serial number (1,2,3...)
        });
        setLoadedSectors(responseData.sectors);
      } catch (err) {}
    };
    fetchContent();
    fetchSectors();
     }, [sendRequest]);

the error: the data that you see I got is the fetchContent, the data I don't get is the fetchSectors
enter image description here

idan noyshul
  • 151
  • 1
  • 9
  • 1
    You can't use the updated state value in the same render cycle that it was set. You can either return from your `fetchContent` and await it before calling the second or some version thereof, OR make another useEffect that is dependent on `loadedContent` which runs the second fetch. – pilchard Jul 25 '22 at 20:13
  • Understand, But I still dont know how to change the code to fix it. can you show me? @pilchard – idan noyshul Jul 25 '22 at 20:26
  • you can add a flag for when the first content is set and based on that use the first content to load into next content - suggestion. – Vishal Torne Jul 25 '22 at 21:17

1 Answers1

1

Just await for the both requests to complete and then update the state.

useEffect(() => {
  const fetchContent = async () => {
    try {
      //...
      return responseData.content;
    } catch (err) {}
  };

  const fetchSectors = async (firstId) => {
    try {
      //...
      return responseData.sectors;
    } catch (err) {}
  };

  const fetchBoth = async () => {
    const tempLoadedContent = await fetchContent();
    const tempLoadedSectors = await fetchSectors(tempLoadedContent[0].id);
    setLoadedContent(tempLoadedContent);
    setLoadedSectors(tempLoadedSectors);
  };

  fetchBoth();
}, []);
Ivan Shumilin
  • 1,743
  • 3
  • 13
  • 18