Reputation:
I am an experienced JavaScript programmer, but am just starting to learn node.js.
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:
this.baseName = /.+(?=\.[^.]+)/.exec(file)[0];
^
TypeError: Cannot read property '0' of null
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:
'0'
within object, instead of index 0
within array.Or I could be making several mistakes:
fs.readdir
and its necessary callback.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
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
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
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