0

I have a two data in cardTypeData :

0: {id: 226, obj: {…}, Slug: 'hello-0'
1: {id: 228, obj: {…}, Slug: 'hello-1'}

useEffect(() => {
      let newcard = [];
      console.log("cardTypeData= ",cardTypeData)
          if (cardTypeData) {
            cardTypeData.map((item) => {
              if(item.Slug){
              const requestUrl = `chartconfig/${item.Slug}/${
                searchQuery?.year
                  ? `?year=${searchQuery.year}${
                      searchQuery.month ? "&month=" + searchQuery.month : ""
                    }`
                  : ``
              }`;
              axiosRequest.get(requestUrl)
              .then((res) => {
                  newcard.push(res.data);
              })
              .catch(console.log('err'))
              // .catch((error)=>{
              //   console.log(error)
              // });
            }
            });
          }
          console.log('list', newcard)
          setCardData(newcard);
      }, [cardTypeData]);

the console output is shown in the figure, how to fix this issues. enter image description here

enter image description here

here data is shown but i could not display it in html.

1
  • Please format your code and include render method as well. Commented Sep 14, 2021 at 16:49

3 Answers 3

2

Refactor, refactor, and refactor again. The above solutions overall work as expected, but could be written better. I hope you do not mind if I show you how it should look like.

function loadNewCards() {
  if (!cardTypeData) return

  cardTypeData.forEach(async (cardItem) => {
    if (!cardItem.Slug) return

    const searchParams = new URLSearchParams(searchQuery).toString()
    const requestUrl = `chartconfig/${cardItem.Slug}/${searchParams}`
    const response = await axios.get(requestUrl).catch(console.log)

    if (!response) return

    setCardData(prevCardData => [...prevCardData, response.data])
  })
}

useEffect(() => {
  loadNewCards()
}, [cardTypeData])

Firstly, please avoid nesting. It makes your code less readable. Try to use negation to avoid nested if / else statement.

if (!cardItem.Slug) return

would be better than

if (item.Slug) {
   const requestUrl = `chartconfig/${item.Slug}`

Secondly, please use URLSearchParams to build the query params. This class will handle your object that contains year and month. I think it is better to have

const searchParams = new URLSearchParams(searchQuery).toString()
const requestUrl = `chartconfig/${cardItem.Slug}/${searchParams}`

instead of

const requestUrl = `chartconfig/${item.Slug}/${
  searchQuery?.year
    ? `?year=${searchQuery.year}${
      searchQuery.month ? '&month=' + searchQuery.month : ''
    }`
    : ``
}`
Sign up to request clarification or add additional context in comments.

Comments

1

Network request is asynhcronous. Before newcard.push(res.data) runs, setCardData(newcard) is already executed with initialized value of newcard which is [ ], ...you can modify the code something similar as below to make it work

useEffect(() => {
      // let newcard = [];
      console.log("cardTypeData= ",cardTypeData)
          if (cardTypeData) {
            cardTypeData.map((item) => {
              if(item.Slug){
              const requestUrl = `chartconfig/${item.Slug}/${
                searchQuery?.year
                  ? `?year=${searchQuery.year}${
                      searchQuery.month ? "&month=" + searchQuery.month : ""
                    }`
                  : ``
              }`;
              axiosRequest.get(requestUrl)
              .then((res) => {
                   
                  ***** modified 👇*****
                  // newcard.push(res.data);
                  setCardData(prev => [...prev, res.data])
              })
              .catch(console.log('err'))
              // .catch((error)=>{
              //   console.log(error)
              // });
            }
            });
          }
          console.log('list', newcard)
          // setCardData(newcard);
      }, [cardTypeData]);

1 Comment

while going to next page from this page and returning back brings more data, i mean while comming back to this page i am getting double data .
1

I've read somewhere that console.log doesn't always run the exact time you call it, sometimes it waits a bit especially when you expand the input.

The problem might be from the api calls from the cardTypeData.map.

Try using for instead to test it out. Also you will have to extract the async part because React doesn't like async useEffect..

Something like this:

const loadNewCards = async () => {
let newcard = [];
console.log("cardTypeData= ", cardTypeData);
if (cardTypeData) {
    for (let item of cardTypeData) {
  if (!item.Slug) {
    const requestUrl = `chartconfig/${item.Slug}/${
      searchQuery?.year
        ? `?year=${searchQuery.year}${
            searchQuery.month ? "&month=" + searchQuery.month : ""
          }`
        : ``
    }`;
    await axiosRequest
      .get(requestUrl)
      .then((res) => {
        newcard.push(res.data);
      })
      .catch(console.log("err"));
  }
}
}
console.log("list", newcard);
setCardData(newcard);
};
useEffect(() => {
    loadNewCards();
}, [cardTypeData]);

And if you worried about performance you should use Promise.all to run all the calls in parallel.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.