I'm trying to make write a node program that will read a file director and filter out those without a certain file extension. (This is a challenge for learnyounode) For some reason it adds to the list 'undefined'. Can anyone tell me why?
var fs = require('fs')
var path = process.argv[2];
var ext = process.argv[3];
var fileList = fs.readdir(path, function callback(err, list){
if (err){
throw err;
}
var filteredList = list.filter(function(fileName){
var extRx = new RegExp('\.' + 'md' + '$');
return extRx.test(fileName);
});
console.log(filteredList.forEach(function(val){console.log(val)}));
});
Outputs:
ACTUAL EXPECTED
"CHANGELOG.md" == "CHANGELOG.md"
"LICENCE.md" == "LICENCE.md"
"README.md" == "README.md"
"undefined" != ""
"" !=
This looks like it's actually an artifact of your console approach. You're console logging each element in the filtered list, and then console logging the output of the forEach function. The forEach function does not have a return value, so it's returning 'undefined' which your outer console log then logs.
Consider changing your console log to just:
console.log(filteredList);
You didn't include a runnable example so it's impossible to tell you what's wrong with the code that you didn't include, espacially when you don't even include the actual list of files that you're trying to filter.
See this example:
var list = [
"CHANGELOG.md",
"LICENCE.md",
"README.md",
"undefined",
"",
];
var filteredList = list.filter(function(fileName){
var extRx = new RegExp('\.' + 'md' + '$');
return extRx.test(fileName);
});
console.log(filteredList);
This correctly filters out the values that you want. Change your program to have one console.log statement to make sure that you know what is being printed:
console.log(filteredList);
or:
console.log(JSON.stringify(filteredList));
One advice - don't complicate it so much:
var filteredList = list.filter(function(fileName){
var extRx = new RegExp('\.' + 'md' + '$');
return extRx.test(fileName);
});
when all you need is:
var filteredList = list.filter(name => name.match(/\.md$/));
You will have less trouble debugging your code if you keep it simple.
After reading the comments I see that the 'md' is just a placeholder and you're using command line arguments in the real code. In that case I would use escape-string-regexp to escape the string. See:
When you use the escape-string-regexp:
var escape = require('escape-string-regexp');
You can do something like:
var extRx = new RegExp('[.]' + escape(ext) + '$');
where ext is the file extension that you got as a command line argument.
The [.] here is just my personal preference of writing a literal dot in regexes, I think it's more readable but it doesn't change any behavior here. The escaping is more important.
If you don't escape the string because you'd like your users to be able to use a custom regex instead of literal strings, then you should at least wrap the new RegExp() call in try/catch because it can throw exceptions on invalid regex syntax.