-5
const randomGIFFunc = async function(dirname) {
  const dirPath = 'src/gifs/' + dirname;
  fs.readdir(dirPath, (err, files) => {
    if (err) {
      console.log('Error reading directory: ', err );
      return;
    }
        
    const randomIndex = Math.floor(Math.random() * files.length);
    const randomGIFname = files[randomIndex];
    const randomGIFpath = dirPath + '/' + randomGIFname;

    console.log('arr in function: ' + [randomGIFpath, randomGIFname]);
    return [randomGIFpath, randomGIFname];
  })
}

later in async code

    switch (act) {
      case 'hug':
        const arr = await randomGIFFunc('hug');
        console.log("arr: " + arr); //undefined
        const randomGIFpath = await arr[0];
        const randomGIFname = await arr[1];
        break;

terminal:

arr: undefined
There was an error running this command: TypeError: Cannot read properties of undefined (reading '0')
arr in function: src/gifs/hug/01.gif,01.gif

Everything I tried is already in code I gave

I can only guess that for some reason the function actually happens later (judging from the terminal logs), but I have no idea why the code isn't waiting for it to finish

3
  • 8
    randomGIFFunc() doesn't return anything. Commented Sep 2 at 19:19
  • If i had to guess, it's an order of operations problem. Based on your console logs you're moving on to the next function before actually receiving data from randomGIFFunc. I would try wrapping the content of randomGIFFunc in a new promise. ie: return new promise((resolve)=> fs.fs.readdir(dirPath, (err, files) ... etc. Then when you have a return currently, you would instead have resolve(return value); Commented Sep 2 at 19:31
  • I have no idea why code isn't waiting for it to finish....because callbacks are designed to be executed later after something external completes. So your code doesn't run until the readdir operation completes and runs the callback you provided to it. That doesn't block the outer function from executing. Make sure you understand asynchronous operations. You didn't await it, so it doesn't block the code you called it from. And you returned from the callback, not from randomGIFFunc(), so the returned value will go back the code in fs that triggered the callback - and it doesn't care. Commented Sep 3 at 7:21

1 Answer 1

3

Your randomGIFFunc does not return anything. It seems like you want to it to return the array from fs.readdir, but you currently only have a return in the callback function of fs.readdir and not the outer randomGIFFunc.

Given that you are using async / await, you probably want to use the Promise version of fs.readdir (instead of the callback variant) and await it as such:

import { readdir } from 'node:fs/promises';

async function randomGIFFunc(dirname) {
  const dirPath = 'src/gifs/' + dirname;
  const files = await readdir(dirPath);
 
  const randomIndex = Math.floor(Math.random() * files.length);
  const randomGIFname = files[randomIndex];
  const randomGIFpath = dirPath + '/' + randomGIFname;

  const arr = [randomGIFpath, randomGIFname];
  console.log('arr in function: ' + arr);
  return arr;
}

You may then want to wrap your calling function (or its calling function etc) with a try/catch in case of error. It wasn't clear from the limited context what would be appropriate to return in case of error, so I did not catch it in my code here (up to you to decide where best to catch it).

You also don't need to await arr in your later code, as the function was already awaited and so returned an array already:

    switch (act) {
      case 'hug':
        const arr = await randomGIFFunc('hug');
        console.log('arr: ' + arr);
        const randomGIFpath = arr[0];
        const randomGIFname = arr[1];
        break;
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.