Trouble listing files with fs.readdir() in Node.js - javascript

I'm working my way through the "Learn You The Node.js For Much Win!" workshop but I'm having trouble on exercise 5. It asks you to Create a program that prints a list of files in a given directory, filtered by the extension of the files.
I passed in the directory, files, that contains an assortment of JavaScript, Ruby, and plain text files. It is supposed to console.log() each file with the .js extension.
var fs = require('fs');
function indexDirectory(directory) {
fs.readdir(directory, function(err, files) {
for (var i in files) {
if (i.indexOf('.js') != -1) {
console.log(files[i]);
}
}
});
}
indexDirectory('files');
My current code does not output anything when I run it with node program.js. Am I missing some asynchronous principle? Am I using callbacks incorrectly? Any help would be appreciated :)

files are array, you should use forEach instead of for .. in
var fs = require('fs');
function indexDirectory(directory) {
fs.readdir(directory, function(err, files) {
files.forEach(function (file) {
if (file.indexOf('.js') != -1) {
console.log(file);
}
});
});
}
indexDirectory('files');

One more problem with this code is that it will print also files with '.json' extension. So instead of indexOf you should use, for example, regular expressions. Something like this:
var matches = new RegExp(".js$").test(files[i]);
if (matches) {
console.log(files[i]);
}

Related

Extract a non ZIP file to files on disk?

I got a App File which is structured like a zip file.
Now I would like to extract all of the files in the app file.
I tried to convert the app to a zip file in the code (just copy and paste as zip file), but then it's a "SFX ZIP Archive", which most of the unzipper in node.js can't read.
For example AdmZip (error message):
rejected promise not handled within 1 second: Error: Invalid CEN
header (bad signature)
var AdmZip = require('adm-zip');
var admZip2 = new AdmZip("C:\\temp\\Test\\Microsoft_System.zip");
admZip2.extractAllTo("C:\\temp\\Test\\System", true)
So now i don't know how to deal with it, because I need to extract the files with all subfolder/subfiles to a specific folder on the computer.
How would you do this?
You can download the .app file here:
https://drive.google.com/file/d/1i7v_SsRwJdykhxu_rJzRCAOmam5dAt-9/view?usp=sharing
If you open it, you should see something like this:
Thanks for your help :)
EDIT:
I'm already using JSZip for resaving the zip file as a normal ZIP Archive. But this is a extra step which costs some time.
Maybe someone knows how to extract files to a path with JSZip :)
EDIT 2:
Just for you information: It's a VS Code Extension Project
EDIT 3:
I got something which worked for me.
For my solution I did it with Workers (Because parallel)
var zip = new JSZip();
zip.loadAsync(data).then(async function (contents) {
zip.remove('SymbolReference.json');
zip.remove('[Content_Types].xml');
zip.remove('MediaIdListing.xml');
zip.remove('navigation.xml');
zip.remove('NavxManifest.xml');
zip.remove('Translations');
zip.remove('layout');
zip.remove('ProfileSymbolReferences');
zip.remove('addin');
zip.remove('logo');
//workerdata.files = Object.keys(contents.files)
//so you loop through contents.files and foreach file you get the dirname
//then check if the dir exists (create if not)
//after this you create the file with its content
//you have to rewrite some code to fit your code, because this whole code are
//from 2 files, hope it helps someone :)
Object.keys(workerData.files.slice(workerData.startIndex, workerData.endIndex)).forEach(function (filename, index) {
workerData.zip.file(filename).async('nodebuffer').then(async function (content) {
var destPath = path.join(workerData.baseAppFolderApp, filename);
var dirname = path.dirname(destPath);
// Create Directory if is doesn't exists
await createOnNotExist(dirname);
files[index] = false;
fs.writeFile(destPath, content, async function (err) {
// This is code for my logic
files[index] = true;
if (!files.includes(false)) {
parentPort.postMessage(workerData);
};
});
});
});
jsZip is A library for creating, reading and editing .zip files with JavaScript, with a lovely and simple API.
link (https://www.npmjs.com/package/jszip)
example (extraction)
var JSZip = require('JSZip');
fs.readFile(filePath, function(err, data) {
if (!err) {
var zip = new JSZip();
zip.loadAsync(data).then(function(contents) {
Object.keys(contents.files).forEach(function(filename) {
zip.file(filename).async('nodebuffer').then(function(content) {
var dest = path + filename;
fs.writeFileSync(dest, content);
});
});
});
}
});
The file is a valid zip file appended to some sort of executable.
The easiest way is to extract it calling an unzipper such as unzipada.exe - free, open-source software available here. Pre-built Windows executables available in the Files section.

Read and Write text file using create-react-app from the browser

I am trying to read a text file that is in the source(src) folder of the react project(creat-react-app), manipulate the values and write back the new value to the same text file.
I am unable to read the values from the file, even though the code that reads the file is logging out old data, not sure where is that coming from. Because even if change the data in the text file directly, it doesn't read the new value.
I am using a package called browserify-fs (https://www.npmjs.com/package/browserify-fs) for reading and writing to a file.
var fs = require('browserify-fs');
var reader = new FileReader();
export const getData = () => {
let initialString = "abcd";
fs.readFile('file.txt', function (err, data) {
if (err) {
return console.error(err);
}
console.log(initialString + data.toString());
});
};
export const writeData = () => {
let data = "abcd";
fs.writeFile("file.txt", data, err => {
// In case of a error throw err.
if (err) throw err;
});
}
Does it have to do something with webpack-loader for importing the types of file for the build or is it related specifically to create-react-app package which defines the files and folder structure for auto-importing types of files?
I am still not sure what is the actual issue causing. Any help would be appreciated.
P.S: I know using CRUD operations on the browser is not a recommended practice, just using for a personal project(learning purpose).

Rename .json file node.js

I want to rename a .json file in node.js this file is dynamically generated and located in the folder /export. the file will always start with contentful-export-XXX.json The XXX could be different on the file, and have random numbers and letters in its place. It is not possible to know the full file name before hand. Therefore I would like to rename the file to contentful-export.json instead of contentful-export-XXX.json. I hope this is clear.
Therefore, I believe that I would need to get the file name from the folder export and then insert this into a fs.rename() but I am unsure how to do this.
Could probably use fs.readdir to get the list of files inside of your export dir and then rename the file with fs.rename
ex.
fs.readdir('/export', function(error, list) {
if (error) throw error;
list.forEach(function(file) {
if (file.includes('contentful-export-') {
fs.rename('/export/' + file, '/export/contentful-export.json')
})
});
});
You can use a regular expression (regex). I think this will match:
/contentful-export-[a-z]*[A-Z]*[0-9]*.json/g
So if you get a list of your files, and see which files matches this regex, you can rename it.
` fs.readdir(path, function(err, items) {
for (var i=0; i<items.length; i++) {
if(item[i].match(/contentful-export-[a-z]*[A-Z]*[0-9]*.json/g){
//do the rename
}
}
}); `
I haven't test it, but should be something like that

How to write to a JSON file in Node

I am currently requiring a JSON file which I am reading data from.
var allUORHours = require('./UORHoursAch.json');
How do I then write to the file? The below doesn't make any changes to the file
allUORHours.test = {};
You may use the File System API's writeFile():
https://nodejs.org/api/fs.html#fs_fs_writefile_file_data_options_callback
No, of course it doesn't. It just changes the variable's value. To write a JSON, you would need to convert to JSON, then write to a file:
var fs = require('fs');
fs.writeFile('./UORHoursAch.json', JSON.stringify(allUORHours), function (err) {
if (err) {
console.log(err);
} else {
console.log("Saved");
}
});

Node.js traverse HTML files and extract angular elements that needs translating

I have a set of html and js files that needs translating. Instead of traditionally copying pasting each keys to a json file, I was wondering if there was a way to do this faster by building a Node JS script. I have a JS script currently which traverses recursively on the directory. And, able to read the current file which is being traversed. But, I want to only extract angular elements that needs to be translated. {{"Welcome" | translate}} <-- HTML $scope.word = {$translate.instant('Export Attendance'); <-- JS Controller
Basically, these are the patterns I want my program to look out for, and only capture the strings into another seperate JSON file.
Currently I have a program that is below.
get_translations.js
var read = require('recursive-readdir-sync');
var fs = require('fs');
try {
root = read('./files/that/has/html/and/js');
} catch (err) {
if (err) {
console.log("File does not exist");
} else {
throw err;
}
}
for (var a=0; a<root.length; a++) {
console.log(root[a]);
fs.readFile(root[a], 'utf-8', function(err, data) {
if (err) {
throw err;
} else {
console.log(data); //need help here.. (noob)
}
});
}
I'd like to avoid JQuery as much as possible. Any light shed on the matter will be greatly apprecieated.
Thanks.
Noob Javascript

Categories