0

I'm using swr in a CRA app and need to use the useSWR hook for data fetching that is both dependant and conditional. What i need to do is:

  1. Call an api to get an id which i will use for a second api call. the id is located in either upcomingEvents or passedEvents .
  2. I want to get it from upcomingEvents but if that array is empty i want to get it from passedEvents.
  3. I know i want the first id in either of the arrays, so using the first index of either array is ok (ex: upcomingEvents[0].id).
  4. Here is an example of the code and the response from the first api call:
const { data: result } = useSWR(`${BASE_URL}/event/${searchEvent}`);
// this second call will wait and run when the first call resolves
const { data: event, error } = useSWR(() => `${BASE_URL}/project/${result.upcomingEvents[0].id}`);

response from first call where i want to get the id for the next call could look like this:

{
  "upcomingEvents": [{"id": "1234"}, {"id": "5678"}, {"id": "0909"}],
  "passedEvents": [{"id": "0987"}, {"id": "6543"}]
}

if i hard code the second api call to use the upcomingEvents[0].id (like in the code example above) i get the response i want.

What i struggle with is where to put the logic that determines which of the id's to use in the depending second api call? I want this logic but can't figure out where without breaking the rules of hooks

  const { data: result } = useSWR(`${BASE_URL}/event/${searchEvent}`);
  const { data: event, error } = useSWR(() =>
   result.upcomingEvents.length > 0
     ? `${BASE_URL}/project/${result.upcomingEvents[0].id}`
     : `${BASE_URL}/project/${result.passedEvents[0].id}`
  );
skyboyer
  • 22,209
  • 7
  • 57
  • 64
dny
  • 1
  • 3

1 Answers1

0

I would do it like this:

  • separate two useSWR requests into separate functions
  • pass null key into second useSWR() when returned value from the first useSWR is falsy. This will ensure the second fetch is skipped if the first one hasn't finished yet.

 const fetcher = url => fetch(url).then(r => r.json())
 
 const useEvents = () => {
  const { data } = useSWR(`${BASE_URL}/event/${searchEvent}`, fetcher);
  return data;
 };
 
 const useEventDetails = () => {
   const events = useEvents();
   let endpoint;

   if (!events) {
     endpoint = null
   }
   else {
    endpoint = events.upcomingEvents.length > 0 ?
     `${BASE_URL}/project/${result.upcomingEvents[0].id}`
     `${BASE_URL}/project/${result.passedEvents[0].id}`;
   }
   
   const { data } = useSWR(`${BASE_URL}/event/${searchEvent}`, fetcher);
   return data;
 }

Ro Milton
  • 2,281
  • 14
  • 9