user3310334
user3310334

Reputation:

Simple JavaScript code does not work with nodejs

I am an experienced JavaScript programmer, but am just starting to learn .

Using node, I want to read the contents of a directory, and print out files of only a specific extension. Both the directory and file-extension will be given by command-line arguments.

But, I also want to push myself and explore JavaScript programming concepts as I solve these puzzles, so I wanted to create a File object to store information about a file, and use that to solve the problem.

Becaause of this, my approach is overly-complex, and I know that there are simpler ways of doing this, but I just want an answer which solves my current problem:

Why does node.js throw the following error

this.baseName = /.+(?=\.[^.]+)/.exec(file)[0];
                                          ^
TypeError: Cannot read property '0' of null

in this code:

function File(file){
  if (file instanceof File) return file;
  if (!(this instanceof File)) return new File(file);

  if (typeof file !== "string") throw new Error("Useful error." + typeof(file));

  this.fullName = file;

  /*vvvvvvvvvvvv  Important Bit  vvvvvvvvvvvvvv*/
  this.baseName = /.+(?=\.[^.]+)/.exec(file)[0];
  this.extension = /[^.]+(?=$)/.exec(file)[0];
}

File.prototype = {
  isOfType: function(ext){
    return ext === this.extension;
  }
}

var fs = require('fs');
var argv = process.argv;

fs.readdir(argv[2], function(err, list){
  var res = list.filter(function(element, index, array){
    var file = new File(element);
    return file.isOfType(argv[3]);
  });
  console.log(res);
});

but, in a Chrome js console, it runs fine (with simulated process and fs objects of course).

To me (inexperienced me) it looks like node could be making several mistakes:

  1. Not handling the regex properly (I've done tests and this seems likely)
  2. Using square brackets to find key '0' within object, instead of index 0 within array.

Or I could be making several mistakes:

  1. Not understanding fs.readdir and its necessary callback.
  2. Not understanding possible differences between constructors in JavaScript and Node

Please help, I'd like an answer that solves or explains my current problem, not one that works around it.

Thanks.

Upvotes: 0

Views: 534

Answers (3)

user3310334
user3310334

Reputation:

It's because any file names which don't match your regular expression, such as many directory names (which are included in your list variable), will then return null here:

/.+(?=\.[^.]+)/.exec(file)

so you are trying to do

null[0]

which will not work.

I solved this by simply checking for a period within the file name:

var file = (element.indexOf(".") > -1) ? new File(element) : false;
return (file) ? file.isOfType(argv[3]) : false;

within the filter, so final code resembles:

fs.readdir(argv[2], function(err, list){
  var res = list.filter(function(element, index, array){
    var file = (element.indexOf(".") > -1) ? new File(element) : false;
    return (file) ? file.isOfType(argv[3]) : false;
  });
  for (var i = 0; i < res.length; console.log(res[i++]));
});

Upvotes: 0

adeneo
adeneo

Reputation: 318302

Node has a built in way to check for valid files

function File(file){
  if (file instanceof File) return file;
  if (!(this instanceof File)) return new File(file);

  if (typeof file !== "string") throw new Error("Useful error." + typeof(file));

  var stat = fs.statSync(file);

  if ( stat && stat.isFile() ) {

      this.fullName = file;

      /*vvvvvvvvvvvv  Important Bit  vvvvvvvvvvvvvv*/
      this.baseName = /.+(?=\.[^.]+)/.exec(file)[0];
      this.extension = /[^.]+(?=$)/.exec(file)[0];
  }
}

Node also has a built in way to get extensions and path names

var path = require('path');

var basename = path.basename(file);

var extension = path.extname(file);

Upvotes: 2

T.J. Crowder
T.J. Crowder

Reputation: 1075159

Why does node.js throw the following error

this.baseName = /.+(?=\.[^.]+)/.exec(file)[0]; ^ TypeError: Cannot read property '0' of null

Because file doesn't match the regular expression, and so exec returns null; then you're doing null[0], which throws the exception. That would happen for a name like a or a., for instance, or the . and .. pseudo-directories.

Use the NodeJS debugger or just console.log file` immediately prior, an you'll see the value that's causing trouble.

Upvotes: 2

Related Questions