Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

chaining `fs.readdir` with a `.then` to return an array

I am trying to create an array of specific files in a directory; which will go through a few test cases to make sure it fits a given criteria.

I'm using the fs.readdir method, but it doesn't return a promise meaning I cannot push to an array.

My idea was to populate an array (arr) with the files I actually want to output and then do something with that array. But because readdir is asynchronous and I can't chain a .then() onto it, my plans are quashed.

I've also tried the same thing with readdirSync to no avail.

const Promise = require('bluebird');
const fs = Promise.promisifyAll(require('fs'));

var arr = [];

fs.readdirAsync(folder).then( files => {
  files.forEach(file => {
    fs.stat(folder + '/' + file, (err, stats) => {
       if(!stats.isDirectory()) {
         arr.push(file);
        return;
      }
     });
   });
})
.then( () => {
  console.log(arr);
});
like image 383
grpcMe Avatar asked May 17 '17 08:05

grpcMe


People also ask

What is the use of FS readdir () method?

The fs.promise.readdir () method defined in the File System module of Node.js. The file System module is basically to interact with the hard disk of the users computer.

How to return only the filenames in a directory using FS?

Example 1: This example uses fs.readdir () method to return the file names or file objects in the directory. Example 2: This example uses fs.readdir () method to return only the filenames with the “.txt” extension.

How to read the contents of a directory asynchronously?

Last Updated : 26 Mar, 2020 The fs.readdir () method is used to asynchronously read the contents of a given directory. The callback of this method returns an array of all the file names in the directory. The options argument can be used to change the format in which the files are returned from the method.

Why does the function readdir return an empty array?

When it reads the directory, fs.promises.readdir (dir); returns an empty array because there is no file in the directory. The function does nothing in the subsequent lines and returns an empty array. Let’s let the function load a directory where there are files in it. I create the following 3 files. We have to consider which tests are necessary.


1 Answers

fs.readdir is callback based, so you can either promisify it using bluebird or Node.js util package (or writing a simple implementation of it yourself), or simply wrap the call in a promise, like so:

// Wrapped in a promise
new Promise((resolve, reject) => {
    return fs.readdir('/folderpath', (err, filenames) => err != null ? reject(err) : resolve(filenames))
})

Or the custom promisify function:

// Custom promisify
function promisify(fn) {
  /**
   * @param {...Any} params The params to pass into *fn*
   * @return {Promise<Any|Any[]>}
   */
  return function promisified(...params) {
    return new Promise((resolve, reject) => fn(...params.concat([(err, ...args) => err ? reject(err) : resolve( args.length < 2 ? args[0] : args )])))
  }
}

const readdirAsync = promisify(fs.readdir)
readdirAsync('./folderpath').then(filenames => console.log(filenames))
like image 65
kristofferostlund Avatar answered Sep 26 '22 01:09

kristofferostlund