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

}
Tf11
  • 93
  • 9

4 Answers4

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);
}
bredikhin
  • 8,875
  • 3
  • 40
  • 44
1

const fs = require('fs');

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

console.log(test());
Danilo Lemes
  • 2,342
  • 1
  • 14
  • 16
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
risingfire
  • 19
  • 4
  • So, `fs.readdir` returns a promise when no callback is passed? Can you point to some documentation where this is described? – Felix Kling Oct 10 '18 at 07:14
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);
}
Behrooz
  • 2,181
  • 1
  • 16
  • 24
  • [Node directly provides promise APIs for fs](https://nodejs.org/api/fs.html#fs_fspromises_readdir_path_options) – Felix Kling Oct 10 '18 at 07:13
  • @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. – Behrooz Oct 10 '18 at 07:19