Writing to file in NodeJS calling from another JS file - javascript

I am having a weird issue writing to a file in NodeJS.
I have this code in my FileHandler.js:
module.exports.writeFile = function (arr) {
var fs = require('fs');
console.log(arr);
var file = fs.createWriteStream(__dirname+'\\test.txt',{encoding: 'utf8'});
file.on('error', function (err) {
console.log(err); });
file.on("finish", function() {
console.log("finished");
});
arr.forEach(function (item) {
file.write(item+"\n");
});
file.end();
}
If I append
exports.writeFile(["1","2","3"])
To the end of this file and then run node FileHandler.js
The file is created correctly.
However, if I call the writeFile function from another .js file as:
var R = require("r-script");
const dataHandler = require("./DataHandler");
const fileHandler = require("./FileHandler");
var out = R(__dirname + "\\apriori.R");
exports.getRules = function () {
dataHandler.getListOfPageVisitsBySession(1000781912582,1530781912582,function (result){
//ignored result variable
fileHandler.writeFile(["1","2","3"]);
})
}
and passing the exact same array to the function it doesn't write anything (but the file is created), neither fires err or finish event.
If it matters, the DataHandler method contains a request module and a GET to another API.
Any clue of the problem?
Thanks in advance

Related

Node javascript require js file?

I just want to load the content of a js file into my variable ! but it's returning me an object ? how can i achieve that ?
server.js
const file = require("./server/file.js");
ctx.body = `${file}`; // Should return "(function () { console.log("ok");})";
//file.js
(function () {
console.log("ok");
});
Use file reader for this, check out this documentation NodeJs website
var fs = require('fs');
fs.readFile('./server/file.js', 'utf8', function(err, data) {
if (err) throw err;
const fileContent = data;
console.log(fileContent);
});
Any CommonJS module will export the value of module.exports which defaults to being an empty object (i.e. what you are seeing).
Your module doesn't explicitly export anything.
It has a function expression that you do nothing with (you don't call it, you don't assign it anywhere, you don't pass it anywhere: it is completely pointless).
If you want to export the function then you need to do so explicitly.
function myFunction() {
console.log("ok");
}
module.exports = myFunction;

JavaScript export array from one file to another to be used. Node.js

Perhaps you can help.
I have a file the is listing the DIR then pushing it to an array. I'm then trying to export it and use it in another file. But its not working....
File 1.js
const fs = require('fs');
let filename = [];
module.exports = function(){
try {
let subfolder = './DIR/';
fs.readdir(subfolder, async (err, files) => {
for (const file of files) {
filename.push(file);
}
});
}
catch (e) {}
};
File 2.js
let instance = require('../../File 2');
console.log(instance);
However when I run this I get an empty array back. however I can console.log within the file 1.js for the array and it shows correctly. Not sure what I'm doing wrong.
You're exporting a function, not an array.
The array will be filled asynchronously. When you console.log in File 2.js, the array will still be empty.
Result was changing File 1.js to be the following:
const fs = require('fs');
module.exports =
{
getRArray: function ()
{
let filename = [];
try
{
let subfolder = './DIR/';
let files = fs.readdirSync(subfolder);
for (let file of files)
{
filename.push(file);
}
}
catch (e)
{
}
return filename;
}
};
with File 2.js
let instance = require('../../DIR');
console.log(instance.getRArray());

Nodejs: Loop Through File and Parse PDFs using Callback in Sync

I am new to node so am struggling quite a bit with the Async nature of it.
I am trying to create a script that will parse the pdfs inside a directory and output them in txt format in another directory.
To do this, I am using fs and pdf2json npm packages. I am passing the parseData function as a callback in the loopingFiles function. The only problem I am having is the async nature of node.
It will loop through all the files at the same time and the output is then a jumbled mess in the last file index.
I would like to process this synchronously such that it will wait once the data is finished parsing to write to the txt and then loop again.
I have tried promises but to no avail. Any help would be much appreciated!
var fs = require('fs'),
PDFParser = require("pdf2json");
let pdfParser = new PDFParser(this,1);
var parseData = function(pdf, index) {
txtFile = "/Users/janet/node/pdf/Destination/".concat(index.toString().concat(".txt"))
pdfFile = "/Users/janet/node/pdf/Source/".concat(pdf);
pdfParser.loadPDF(pdfFile);
// Parsing the pdf file in question
pdfParser.on("pdfParser_dataError", errData => console.error(errData.parserError) );
pdfParser.on("pdfParser_dataReady", pdfData => {
fs.writeFile(txtFile, pdfParser.getRawTextContent());
});
};
var loopingFiles = function(callback) {
fs.readdir("/Users/janet/node/pdf/Source", function (err, files) {
if (err) {
console.log(err);
} else {
files.forEach( function(file, index) {
callback(file, index);
});
};
});
};
loopingFiles(parseData);
Something like this?
var fs = require("fs"),
PDFParser = require("pdf2json");
let pdfParser = new PDFParser(this, 1);
var parseData = function(pdfs, index = 0) {
// finished
if (index >= pdfs.length) return;
let pdf = pdfs[index];
txtFile = "/Users/janet/node/pdf/Destination/".concat(
index.toString().concat(".txt")
);
pdfFile = "/Users/janet/node/pdf/Source/".concat(pdf);
// Parsing the pdf file in question
pdfParser.on("pdfParser_dataError", errData => {
console.error(errData.parserError)
// not sure if you want to call this here to keep going or not
parseData(pdfs, index + 1);
});
pdfParser.on("pdfParser_dataReady", pdfData => {
fs.writeFile(txtFile, pdfParser.getRawTextContent(), function() {
// when we're all done, call this function again, with the index of the next pdf
parseData(pdfs, index + 1);
});
});
pdfParser.loadPDF(pdfFile);
};
var loopingFiles = function(callback) {
fs.readdir("/Users/janet/node/pdf/Source", function(err, files) {
if (err) {
console.log(err);
} else {
callback(files, 0);
}
});
};
loopingFiles(parseData);
the main difference is passing the whole array of pdfs to the function with an index, and only calling that function again with an incremented index once the current one is completed

How to make a synchronous module in NodeJS

I already asked the question but I fele like I didn't asked it properly.
I'm trying to make a little encryption module in NodeJS but I have a very hard time with the asynchronous nature of it.
First of, the result variable in my main file is undefined a milisecond after the script is called, I was expecting that.
Also, the file is processed while the encryption occur, not before.
Note that I do not wish to encrypt the file itself.
The big question:
How can I make everything run smoothly and in order? :D
www.js
var mod = require('./mymodule.js')
var result = mod.doencrypt();
mymodule.js
module.exports.doencrypt = function() {
var content = processFile(); //Open a file, increment counter
var key = generateKey();
var iv = generateIV();
var encrypt = doEncryption(content);
return encrypt;
}
//File manipulation
async function openFile() {
return new Buffer(await readFile('monolitic.txt', "binary"));
}
async function saveFile(bin) {
await fs.writeFile("monolitic.txt", bin, "binary", function(err) {
if(err) {
console.log(err);
} else {
console.log("The monolitic file was saved!");
return bin;
}
});
}
function processFile() {
console.log("Reading buffer")
openFile().then(function (bin) {
monoCounter = bin;
//Increment
inc(monoCounter);
console.log(monoCounter);
monoCounter = saveMonoCounter(monoCounter);
return monoCounter;
}).catch((err) => {
monoCounter = Buffer.alloc(128);
saveMonoCounter(Buffer.alloc(128));
});
}

Modules with Arguments NodeJS

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)
});
}
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);
}
});
}
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:
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.
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);

Categories

Resources