0

I have a program that reads some data from my disk and converts it into an array of objects. When logging the array mentioned earlier, it is okay. But if I try to log or access a specific element in the array, undefined is logged instead. Here is my code:

  const [studies, setStudies] = useState<Study[]>();
  const [cameraStations, setCameraStations] = useState<CameraStation[]>();

  useEffect(() => {
    const tempStudyArr: Study[] = [];
    const tempCameraArr: CameraStation[] = [];

    const studiesPromise = Promise.resolve(getStudies());
    studiesPromise.then((value) => value.forEach((item) => {
      tempStudyArr.push(item);
      const cam = Promise.resolve(getCameraStations(item))
      cam.then((value) => value.forEach((v) => {
        tempCameraArr.push(v);
      }))
    }));
    
    setCameraStations(tempCameraArr);
    setStudies(tempStudyArr);
  }, [])

  if (studies == undefined) return null;
  if (cameraStations == undefined) return null;
  if (studies[0] == undefined) return null;

  console.log(studies[0])
  console.log(cameraStations) 
  console.log(cameraStations[0]) //<----- Ouputs "undefined"

getCameraStations and getStudies are defined like this:

async function getCameraStations(study: Study) {
  return await window.datastore.getCameraStations(study);
}

async function getStudies() {
  return await window.datastore.getStudies();
} 

This is the output from the console:

Console Ouput

EDIT: Some users linked similar questions related to console.log, and now I understand why undefined is being logged. Now my question is how do I index into that variable at all? If I put

if (cameraStations[0] == undefined) return null;

before the console.log, the component never renders and always returns null. If I pass the cameraStations array into a function, that function also says that the contents are undefined. How do I wait for the data inside the cameraStations array to be filled before interacting with it?

SOLUTION EDIT Fixed my issue by creating and using an async function inside the useEffect to get the data. See below.

useEffect(() => {
    const getData = async () => {
      const studiesList = await window.datastore.getStudies();

      const stations: CameraStation[][] = await Promise.all(
        studiesList.map(async (study) => {
          const cameras = await window.datastore.getCameraStations(study);
          return cameras
        })
      );

      setStudies(studiesList);
      setCameraStations(stations);
    }
    getData().catch(console.error);
  }, [])
  • 2
    the console is showing live data, and is updated as that data is changed. Your method to get data is asynchronous - you're trying to log it before its been read. – Jamiec Aug 07 '23 at 17:33
  • Output `Array(0)` sounds like an empty array, that's why index 0 is undefined – Hans Kesting Aug 07 '23 at 17:34
  • Regarding your edit: You'd generally use something like `cameraStations?.length` to check that the array exists and has content. – DBS Aug 08 '23 at 14:18
  • @DBS the issue with that is it always evaluates to 0. I can't seem to "wait" for the element to be populated. – Nakul Kumar Aug 08 '23 at 14:47

0 Answers0