Home > Blockchain >  How to handle two get request that the second request depend on the first one using setState in Reac
How to handle two get request that the second request depend on the first one using setState in Reac

Time:12-28

I'm new to React, and I know that useState will not be reflected immediately.

In my first get request I'm getting page informations based on URL instead of pageID because I'm trying to make a custom url when sharing pages instead of looks like this: http://localhost:3000/pages/:pageId, so it becomes http://localhost:3000/pages/DT/:url. In the second get request, I'm getting templates based on pageID to render templates (houses).

Since I'm not using pageID, I cannot use useParams to get the value. Instead, I'm trying to set pageID like this in the first get request (setPageId(res.data.page.id))

But since I cannot get pageID from the first get request, the second request becomes http://localhost:8080/api/RE/template/null.

I've tried localStorage.setItem("pageId", res.data.page.id) it works, but I don't want to use local storage set or remove every time. I also tried to make a setTimeout for 2 seconds but still it didn't work. In the useEffect I've added pageID as a dependency but still nothing.. I've also tried using Promise and later made like this but pageID returns null as well.

useEffect(() => {
    getCustomUrl()
      .then(() => {
        getTemplates();
      })
      .catch((err) => {
        console.log(err);
      });
  }, []);

What I want to know is, what is the best approach to handle two request that depends on each other?

  const [loadedSharePages, setLoadedSharePages] = useState(null);
  const [loadedTemplates, setLoadedTemplates] = useState([]);
  const [pageId, setPageId] = useState(null);

  const url = useParams().url;

  const getCustomUrl = async () => {
    await axios({
      method: "GET",
      url: `http://localhost:8080/api/pages/DT/${url}`,
      headers: {
        Authorization: "Bearer "   localStorage.getItem("token"),
      },
    })
      .then((res) => {
        console.log("Respond from the request getCusomUrl-->", res);
        setLoadedSharePages(res.data.page);
        setPageId(res.data.page.id);
      })
      .catch((err) => {
        console.log(err);
      });

    console.log("Shared page --> ", loadedSharePages);
    console.log("pageid: ", pageId);
  };

  const getTemplates = async () => {
    await axios({
      method: "GET",
      url: `http://localhost:8080/api/RE/template/${pageId}`,
      headers: {
        "Content-Type": "multipart/form-data",
        Authorization: "Bearer "   localStorage.getItem("token"),
      },
    })
      .then((res) => {
        console.log("Respond from the request -->", res);
        setLoadedTemplates(res.data.templates);
        console.log("Res.data.templates -->", res.data.templates);
      })
      .catch((err) => {
        console.log(err);
      });

    console.log("Loaded Templates --> ", loadedTemplates);
  };

  useEffect(() => {
    getCustomUrl();
    getTemplates();
  }, []);

CodePudding user response:

Do separate Effect for each request that depends on the previous. This is one simple solution.

You can then think how to do a custom hook for this, etc.

You can set the effect to be depend on some state by adding it to the brackets at the effect parameter.

For example: (like pseudocode code)

useEffect(()=> ...getTheFirstData. then(//update the state1) ,[stateStartAction]);

//will happen when state1 has changed
useEffect(()=> ...getTheSecondData. then(//update the next state) ,[state1]);

//And so on what you need 

on the code trigger the effect by:

setStartAction(!stateStartAction);

CodePudding user response:

I'd recommend to extract actual api requests to something more independent with parameters and without setting the state inside. That way you will be able to move those functions to a separate api.js file (for example) and you will be able to reuse them later, keeping the actual components code clear.

This approach might help you:

const getCustomUrl = (url) => {
  return axios({
    method: "GET",
    url: `http://localhost:8080/api/pages/DT/${url}`,
    headers: {
      Authorization: "Bearer "   localStorage.getItem("token")
    }
  }).then((res) => {
    console.log("Respond from the request getCusomUrl-->", res);
    return res.data;
  });
};

const getTemplates = (pageId) => {
  return axios({
    method: "GET",
    url: `http://localhost:8080/api/RE/template/${pageId}`,
    headers: {
      "Content-Type": "multipart/form-data",
      Authorization: "Bearer "   localStorage.getItem("token")
    }
  }).then((res) => {
    console.log("Respond from the request -->", res);
    return res.data;
  });
};

useEffect(() => {
  async function fetchMyAPI() {
    const getCustomUrlData = await getCustomUrl(url);
    const getTemplatesData = await getTemplates(getCustomUrlData.page.id);
    
    setLoadedSharePages(getCustomUrlData.page);
    setPageId(getCustomUrlData.page.id);
    setLoadedTemplates(getTemplatesData.templates);
  }
  fetchMyAPI().catch(console.error);
}, []);

CodePudding user response:

This one solved my problem.

const getCustomUrl = async () => {
    try {
      const res = await axios({
        method: "GET",
        url: `http://localhost:8080/api/pages/DT/${url}`,
        headers: {
          Authorization: "Bearer "   localStorage.getItem("token"),
        },
      });

      setLoadedSharePages(res.data.page);
      setPageId(res.data.page.id);

      return res.data.page.id;
    } catch (err) {
      console.log(err);
    }
  };

  const getTemplates = async () => {
    try {
      const pageId = await getCustomUrl();
      const res = await axios({
        method: "GET",
        url: `http://localhost:8080/api/RE/template/${pageId}`,
        headers: {
          "Content-Type": "multipart/form-data",
          Authorization: "Bearer "   localStorage.getItem("token"),
        },
      });

      setLoadedTemplates(res.data.templates);
      console.log("Res.data.templates -->", res.data.templates);
    } catch (err) {
      console.log(err);
    }
  };

 useEffect(() => {
    getTemplates();
  }, []);
  • Related