4

Inside a function, I would like to set the value of a variable (foldersInDir) to the results of getting the contents of a directory using fs.readdir();

I thought using await would force the console.log line to wait for a response, but it's not.

How can I set foldersInDir = the return value?

/*Begin function*/
const listContents = async (myPath) => {

    var fs = require('fs');

    let foldersInDir = await fs.readdir(myPath, function(err, items) {
        console.log(items); //works
        return  items;
    });

    console.log(foldersInDir); //does not work, undefined

}
4

4 Answers 4

1

You need to convert readdir to a promise, e.g.:

const foldersPromised = (path) =>
  new Promise((resolve, reject) =>
    fs.readdir(path, (err, items) =>
      err !== undefined ? reject(err) : resolve(items)
    )
  );
try {
  let foldersInDir = await foldersPromised(myPath);
} catch(err) {
  console.log(err);
}
Sign up to request clarification or add additional context in comments.

5 Comments

Good point, turns out it's already there starting with v10. Thanks for the heads-up!
@bredikhin - I get null when I try to console out foldersInDir
@Tf11 Hmm, maybe a scope issue? As per the listing foldersInDir will only exist within the try block.
@FelixKling unfortunately we are running v8 on prod now.
1

const fs = require('fs');

const test = () => {
        let folders = fs.readdirSync('.');
        return folders;
}

console.log(test());

Comments

1

Edit: sorry, need to promisify() the function

const fs = require('fs');
const { promisify } = require('util') // available in node v8 onwards
const readdir = promisify(fs.readdir)

async function listContents() {
  try {                                         // wrap in try-catch in lieu of .then().catch() syntax
    const foldersInDir = await readdir(myPath)  // call promised function
    console.log('OK, folders:', foldersInDir)   // success
  } catch (e) {
    console.log('FAIL reading dir:', e)         // fail
  }  
}

listContents('path/to/folder') // run test

1 Comment

So, fs.readdir returns a promise when no callback is passed? Can you point to some documentation where this is described?
0

I recommend using the promisify function provided by Node.js to fix the problem. This function will convert a callback-based function to a promise-based function, which can then be used using the await keyword.

const fs = require('fs');
const {
  promisify
} = require('util');

const readdirAsync = promisify(fs.readdir);

/*Begin function*/
const listContents = async(myPath) => {
  let foldersInDir = await readdirAsync(myPath);

  console.log(foldersInDir);
}

2 Comments

@FelixKling I agree that it’s an alternative, but to be fair, it’s an experimental API added in the latest version of Node.js. For now, promisify seems to be more stable.

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.