0

I have two files, home.js and module.js in the same directory. What I'm trying to do is, I'm trying to pass the variable named directory as I call the function I exported from module.js.

It gives me this error: binding.readdir(pathModule._makeLong(path), req); Type error: path must be a string.

What I'm trying to figure out is, I've passed the directory variable which is process.argv[2] (contains the path) from home.js as I call the function in module.js that requires the same argument (path).

home.js

var fs = require('fs');

var path = require('path');
var module = require('./module.js');
var directory = process.argv[2];
var extensionRequired = process.argv[3];

function printList(err, data) {
    if(err) return err;
    list.forEach(function (file) {
        if(path.extname(file) === '.' + extensionRequired) {
            console.log(file);
        }
    });
}

module(directory, extensionRequired, printList);

module.js

var fs = require('fs');
var path = require('path');

module.exports = function (directory, extensionRequired, callBack) {
    fs.readdir(directory, function(err, list) {
        if(err) return err;
        callBack(err, list)
    });
}
2
  • Is it me, or you did not define the list variable in your home.js file Commented Feb 13, 2016 at 18:19
  • Can we see the command that launches node with the arguments? Commented Feb 13, 2016 at 18:19

2 Answers 2

1

I think you made a mistake, and forgot to rename the list variable:

function printList(err, data) {
    if(err) return err;
    // Here list => data
    data.forEach(function (file) {
        if(path.extname(file) === '.' + extensionRequired) {
            console.log(file);
        }
    });
}
Sign up to request clarification or add additional context in comments.

Comments

0

In your callback-method, named printList, you set the second argument as data. If you want to access the second argument's value again, you have to use data in your code or reassign it to another variable.

Your method may then look like this:

function printList(err, data) {
  if (err) return err;
  data.forEach(function (file) {
    if(path.extname(file) === '.' + extensionRequired) {
        console.log(file);
    }
  });
}

Additionally, I see two more problems with your code:

  1. In module.js, you're requiring the parameter extensionRequired. If you look closely, you'll find, that it isn't even used in this method. This isn't really an error, but would in my opinion be seen as inelegant. Rather pass it trough to the printList as an additional argument (more the node-typical way IMHO) or use it as a global-scope variable as you are currently doing anyway.

  2. In your module.exports-anonymous function from module.js, you are using if (err) return err;. I'd highly recommend you to not do such a thing. Because this is an asynchronous method, you can't really return something, as the return-statement might actually be executed after you called this method. Instead, pass your error as the first argument of the callback. If there is no error, pass null instead, so you can easily figure out if something unexpected happened. Always check that!

Your module.js could then look something like this:

var fs = require('fs');
var path = require('path');

module.exports = function (directory, callback) {
  fs.readdir(directory, function(err, list) {
    if (err)
      // Error happened, pass it to the callback 
      callback(err);
    else 
      // Everything ran smooth, send null as the error (no error)
      // and the list as the second argument.
      callback(null, list)
  });
}

Your home.js should then be changed accordingly:

var fs = require('fs');

var path = require('path');
var module = require('./module.js');
var directory = process.argv[2];
var extensionRequired = process.argv[3];

function printList(err, data) {
  if (err) {
    console.error("An error occurred:", err);
    // Exit with an error-code of one to 
    // tell failure to the calling process and
    // prevent printing the probably 'undefined' data-variable
    process.exit(1);
  }
  data.forEach(function (file) {
    if(path.extname(file) === '.' + extensionRequired) {
      console.log(file);
    }
  });
}

// extensionRequired removed, as it is not needed
module(directory, printList);

2 Comments

I checked my code since it's more organized that way (I failed to notice since I'm stuck with the error) but it still gives the same error: binding.readdir(pathModule._makeLong(path), req); Type error: path must be a string.
If you just copy/paste the coded i've written into the separate files, it'll run perfectly (at least as I would expect it to run). I'm on a Unix-System and therefore running node home.js $HOME txt, which prints out all the txt-files inside my home-directory like so: test1.txt[line break] test2.txt[line break] test3.txt Don't have any experience with node on Windows but I'd expect it to work there too. Your error would finally lead me to the assumption, that your calling your script with the wrong arguments. Could you please provide them?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.