skip to Main Content

I need to make two separate api calls in the same react component. However, I’m having trouble getting information when I try to use it in my HTML. Specifically the similar data in this code.

function Info() {

  let params = useParams();
  const [details, setDetails] = useState({});
  const [similar, setSimilar] = useState({});
  const [activeTab, setActiveTab] = useState('instructions')

  const fetchDetails = async () => {
    const data = await fetch(`https://api.spoonacular.com/recipes/${params.name}/information?apiKey=${process.env.REACT_APP_API_KEY}`)
    const detailData = await data.json();
    setDetails(detailData);
    console.log(detailData);
  };

  const fetchSimilar = async () => {
    const data = await fetch(`https://api.spoonacular.com/recipes/${params.name}/similar?apiKey=${process.env.REACT_APP_API_KEY}`)
    const similarData = await data.json();
    setSimilar(similarData);
    console.log(similarData);
  };

  useEffect(() => {
    fetchDetails();
    fetchSimilar();
  }, [params.name]);


  return (
   <DetailWrapper>
    <div>
      <h2>{details.title}</h2>
      <img src={details.image} alt={details.title} />
    </div>
    <InfoDiv>
      <Button className={activeTab === 'instructions' ? 'active' : ''} onClick={() => setActiveTab('instructions')}>Instructions</Button>
      <Button className={activeTab === 'ingredients' ? 'active' : ''} onClick={() => setActiveTab('ingredients')}>Ingredients</Button>
      {activeTab === 'instructions' && (
        <div>
          <p dangerouslySetInnerHTML={{__html: details.summary}}></p>
          <p dangerouslySetInnerHTML={{__html: details.instructions}}></p>
        </div>
      )}

      {activeTab === 'ingredients' && (
        <ul>
          {details.extendedIngredients.map((ingredients) => (
            <li key={ingredients.id}>{ingredients.original}</li>
          ))}
        </ul>
      )}
    </InfoDiv>
    <div>
      <p>{similar.title}</p>
    </div>
   </DetailWrapper>
  )
}

ferent way I should be making multiple calls in one file? Should I fetch both url data in one function instead of two?

I already tried to make a separate component which holds the data I need however I still got the same results. This leads me to believe that its just how I’m calling this request.

2

Answers


  1. Putting the function call inside useEffect with the params in the dependency means that the functions are only called when the params.name changes. If they are not being called, then the issue may be due to params.name not changing. Try it with an empty array to see if the data is fetched once, before adding the dependency. That way you can tell if the issue is with the dependency or the function call itself.

      useEffect(() => {
        fetchDetails();
        fetchSimilar();
      }, []);
    
    Login or Signup to reply.
  2. The issue with your code is that you are setting the state of similar and details to an empty object {} initially, and then trying to access properties of these object in your HTML before the API call has returned and updated the state. Therefore, you are not seeing any data from the similar API call in your HTML.

    To resolve this issue, you can use an optional chain operator ? before invoking any keys from the similar and details objects. This will safeguard against any null or undefined values that may exist before the API calls return and update the state. For instance:

        <div>
          <h2>{details?.title}</h2>
          <img src={details?.image} alt={details?.title} />
        </div>
    

    or you can add a check in your HTML to only render the similar data if it exists.

    Regarding your question about making multiple API calls in one file, your current approach of using separate functions to fetch each API endpoint and calling them both in the useEffect hook is a valid approach. Fetching both URLs in one function would also work, but might not be necessary unless you need to coordinate the results of both calls in some way.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search