Displaying node.js file inside a node.js server? - javascript

Trying to display this node.js file through my node.js server. However, all it does is display the code in proper format as if it were in notepad rather than actually displaying what it does in the console when executed. So in other words, I want my node.js file to execute and display on the browser, not just have the code display on the webpage.
var fs = require('fs');
var colour = require('colour');
var array = fs.readFileSync('songs/sister_golden_hair.txt').toString().split("\n");
var chordsArray =[];
var lyricsArray =[];
var count1 = 0;
for(var line in array) {
count1++;
if (count1 >= 3) {
var count2 = 0;
lyricsArray[count1-3] = [];
chordsArray[count1-3] = [];
while (array[line].indexOf("[") != -1) {
lyricsArray[count1-3][count2] = array[line].substring(0, array[line].indexOf("["));
array[line] = array[line].substring(array[line].indexOf("[")+1, array[line].length);
chordsArray[count1-3][count2] = array[line].substring(0, array[line].indexOf("]"));
array[line] = array[line].substring(array[line].indexOf("]")+1, array[line].length);
count2++;
}
if (array[line].length > 0) {
lyricsArray[count1-3][count2] = array[line];
chordsArray[count1-3][count2] = "";
}
}
else {
console.log(array[line]);
}
}
for (var i = 0; i < chordsArray.length; i++) {
for (var j = 0; j < chordsArray[i].length; j++) {
if (j == 0) {
for (var k = 0; k < lyricsArray[i][j].length; k++) {
process.stdout.write(" ");
}
process.stdout.write(chordsArray[i][j].green);
}
else {
for (var k = 0; k < lyricsArray[i][j].length - chordsArray[i][j-1].length; k++) {
process.stdout.write(" ");
}
process.stdout.write(chordsArray[i][j].green);
}
}
console.log();
for (var j = 0; j < lyricsArray[i].length; j++) {
process.stdout.write(lyricsArray[i][j].yellow);
}
}
and here is the node.js server I am running where I try to say that if the client goes to "http://127.0.0.1/sister_golden_hair.html" then it should display the above node.js Here is the node.js server:
var http = require('http');
var fs = require('fs');
var counter = 1000;
function serveStaticFile(res, path, contentType, responseCode){
if(!responseCode) responseCode = 200;
fs.readFile(__dirname + path, function(err, data){
if(err){
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('[' + counter++ + ']: ' + '500 INTERNAL FILE ERROR' + '\n');
}
else {
res.writeHead(responseCode , {'Content-Type': contentType});
res.end(data);
}
});
}
http.createServer(function (request,response){
var path = request.url.replace(/\/?(?:\?.*)$/,'').toLowerCase();
//write HTTP header
var page = '';
switch(path){
case '/sister_golden_hair.html':
serveStaticFile(response,
'/Problem4.js',
'application/javascript');
break;
}
}).listen(3000, "127.0.0.1");
console.log('Server Running at http://127.0.0.1:3000 CNTL-C to quit');

If you want to use node.js code in the browser, you're going to need to use something like browserify.

Have you tried using eval() - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval ? Check out the warning though.

Related

Node.js fs.readFile returns previous version of the file

I made this code:
var Discord = require('discord.js');
var client = new Discord.Client();
var fs = require('fs');
var dotenv = require('dotenv');
var option = require('./assets/config.json');
dotenv.config({
path: __dirname + '/assets/.env'
});
client.on('ready', function () {
console.log(`Logged in as ${client.user.tag}`);
});
client.on('message', function (message) {
var done = false;
if (!message.content.startsWith('/')) return;
var args = message.content.substr(1).split(' ');
fs.readdir('./cmd/', function (err, list) {
for (var i = 0; i < list.length; i++) {
var cmds = require(`./cmd/${list[i]}`);
for (var x = 0; x < cmds.alises.length; x++) {
for (var a = 0; a < args.length; a++) {
if (args[a] == cmds.alises[x] && !done) {
cmds.run(client, message, args, option);
done = true;
}
}
}
}
});
});
client.login(process.env.TOKEN);
And I thought that I don't have to restart this main file when I edit the module files because in this code Node.js reads all the files instantly on messages. But when I edit the module file, I should restart the main file. Why is this thing happens?

Express server not responding to reqs

After sending a bunch of POST/GET reqs to the server my server stops responding and in the network tab of the console all the reqs are labeled as "pending".
I have logged timestamps during the responses but they go fast and they just don't run once the problem occurs.
Sever:
var ip = require('ip');
var fs = require('fs');
var bodyParser = require('body-parser');
var path = require('path');
var express = require('express');
var app = express();
var expressWs = require('express-ws')(app);
var students = [];
var cons = [];
app.use(bodyParser.text({
extended: true
}));
app.post('/add', function(req, res) {
students.push(req.body);
for (var i = 0; i < cons.length; i++) {
cons[i].send(JSON.stringify(students));
}
});
app.post('/del', function(req, res) {
for (var i = 0; i < students.length; i++) {
if (students[i] == req.body) {
students.splice(i, 1);
}
}
for (var i = 0; i < cons.length; i++) {
cons[i].send(JSON.stringify(students));
}
});
app.get('/students', function(req, res) {
res.send(JSON.stringify(students));
});
app.ws('/mes', function(ws, req) {
cons.push(ws);
ws.on('close', function(req) {
for (var i = 0; i < cons.length; i++) {
if (cons[i] == ws) {
cons.splice(i, 1);
}
}
});
});
Sender:
function sendData() {
if (okMes() == true) {
console.log(student_i.value);
fetch('/add', {
method: 'POST',
body: student_i.value
})
.catch(function(err) {
console.error(err);
});
student_i.value = '';
}
}
Reciever:
function placeButton(data) {
if (data.length == 0) {
error_p.style.display = 'block';
error_p.innerHTML = 'No New Students';
}
for (var i = 0; i < 200; i++) {
if (document.getElementById(i) != null) {
document.getElementById(i).remove();
}
}
students = [];
for (var i = 0; i < data.length; i++) {
student = document.createElement('button');
student.innerHTML = data[i];
students_d.appendChild(student);
students.push(student);
student.setAttribute('id', students.length - 1);
error_p.style.display = 'none';
}
for (var i = 0; i < students.length; i++) {
students[i].onclick = function() {
for (var i = 0; i < students.length; i++) {
if (students[i] == this) {
students.splice(i, 1);
}
}
// document.getElementById(this.getAttribute('id')).remove();
fetch('/del', {
method: 'POST',
body: this.innerHTML
});
if (document.querySelectorAll('button') == []) {
error_p.style.display = 'block';
error_p.innerHTML = 'No New Students';
}
}
}
}
// seting interval and fetching for '/students' and calling this func
// reciving ws.onmessage and calling this func
I have no idea why my reqs aren't being responded to and if anyone could help that would be great.
Fetch API expects full url. Change your fetch call to:
// assuming you're running on localhost on port 3000
fetch('http://localhost:3000/del', {
method: 'POST',
body: this.innerHTML
});
I just figured out the answer while testing my code. It turned out I didn't res.end() when handling post reqs and I guess it the reqs might have timed out.

Node.js writing data to file results in additional written characters

as the title says, when i try to save data to a file using the filesystem function fs.writeFile(), sometimes the file has extra data on it.
My code:
fs.writeFile('path', JSON.stringify(data), function (err) {});
May be its because of the JSON.stringify(), or its a problem of the fs.writeFile.
If you need additional information, im willing to give it!
More code:
function CheckLeaderBoards(player, tag, points) {
fs.readFile(datapath + '/data/topplayers.json', function(err, data) {
var lb = JSON.parse(data);
var isin = false;
for (let i = 0; i < lb.length; i++) {
if (lb[i].tag == tag) {
isin = true;
lb[i].points = points;
break;
}
}
if (!isin)
lb.push({"player": player.toString(), "tag": tag.toString(), "points": parseInt(points)});
for (let i = 0; i < lb.length; i++) {
var bestpoints = -100;
var bestindex = 0;
for (let j = i; j < lb.length; j++) {
if (lb[j].points > bestpoints) {
bestpoints = lb[j].points;
bestindex = j;
}
}
lb = ChangeArrayIndex(lb, bestindex, i);
}
fs.writeFile(datapath + '/data/topplayers.json', JSON.stringify(lb), function (err) {});
})
}
function ChangeArrayIndex(array, fromIndex, toIndex) {
var arr = [];
for (let i = 0; i < array.length; i++) {
if (i == toIndex) arr.push(array[fromIndex]);
if (i == fromIndex) continue;
arr.push(array[i]);
}
return arr;
}
Basicly i want to write a leaderboard, i have an array of JSON Objects, ex: {"player":"Bob","tag":"a10b","points": 10},...
To write in a file, you to open the file, in callback you will get file descriptor that descriptor will be used to write in the file. Please see example:
fs.open(datapath + '/data/topplayers.json', 'wx', function(error, fileDescriptor){
if(!error && fileDescriptor){
var stringData = JSON.stringify(data);
fs.writeFile(fileDescriptor, stringData, function(error){
if(!error){
fs.close(fileDescriptor, function(error){
if(!error){
callback(false);
}else{
callback('Error in close file');
}
});
}else{
callback('Error in writing file.');
}
});
}
}
Ok, If you want to update the file, please check this code:
const myUpdaterFcn = (dir,file,data,callback)=>{
//dir looks like this: '/your/existing/path/file.json'
// Open the file for writing (using the keyword r+)
fs.open(dir, 'r+', (err, fileDescriptor)=>{
if(!err && fileDescriptor){
// Convert data to string
const stringData = JSON.stringify(data)
// Truncate the file
fs.truncate(fileDescriptor,err=>{
if(!err){
// Write to file and close it
fs.writeFile(fileDescriptor, stringData,err=>{
if(!err){
fs.close(fileDescriptor,err=>{
if(!err){
callback(false)
} else {
callback('Error closing existing file')
}
})
} else {
callback('Error writing to existing file')
}
})
} else {
callback('Error truncating file')
}
})
} else {
callback('Could not open file for updating, it may not exist yet')
}
})
}
Good Luck.

Can't process multiple pdf files using pdf2json for nodejs

I'm using https://github.com/modesty/pdf2json to parse multiple pdf files. It works with 1 single file, but when trying to load multiple files, the pdfParser_dataReadyevent seems to fire always with the same file.
This is what i've tried
var PDFParser = require('pdf2json');
var pdfParser = new PDFParser();
var fs = require('fs');
var fileNames = [];
var fileCont = 0;
fs.readdir(fileFolder, function(err, files){
for (var i = files.length - 1; i >= 0; i--) {
if (files[i].indexOf('.pdf') !== -1){
fileNames.push(files[i]);
}
pdfParser.loadPDF(fileNames[fileCont]);
});
pdfParser.on('pdfParser_dataReady', function(data){
//Do all my stuff and insert in db...
fileCont++;
If (fileCont === fileNames.lenght){
for (var i = fileNames.length - 1; i >= 0; i--) {
fs.unlink(fileFolder + fileNames[i]);
}
return res.json({
data: 'ok '
});
}
pdfParser.loadPDF(fileFolder + fileNames[fileCont]);
});
I managed to make pdf2json work with multiple files by creating a new PDFparser in each iteration. This is not a very 'pretty' way to manage multiple pdf files, the library should have an easy way of doing it, but it works!
var PDFParser = require('pdf2json');
var fs = require('fs');
var fileNames = [];
var fileFolder = 'myFolder/';
var fileCont = 0;
var loadPDF = function(filePath){
if(fileNames.length === fileCont){
//Insert in db and add any FINAL code, then return;
}
else{
//Call for another file to process
var pdfParser = null;
pdfParser = new PDFParser();
pdfParser.loadPDF(filePath);
pdfParser.on('pdfParser_dataError', function(err){
//Handle pdfParser error
});
pdfParser.on('pdfParser_dataReady', function(data){
//Get the pdf data and process it
fileCont++; //increase the file counter
loadPDF(fileFolder + fileNames[fileCont]); //parse the next file
});
}
};
fs.readdir(fileFolder, function(err, files){
for (var i = files.length - 1; i >= 0; i--) {
if (files[i].indexOf('.pdf') !== -1){
fileNames.push(files[i]);
}
}
loadPDF(fileFolder + fileNames[fileCont]);
});

'Juggling Async' - Why does my solution not return anything at all?

After asking a question and getting a very helpful answer on what the 'Async Juggling' assignment in learnyounode was asking me to do, I set out to implement it myself.
The problem is, my setup isn't having any success! Even though I've referred to other solutions out there, my setup simply isn't returning any results when I do a learnyounode verify myscript.js.
GIST: jugglingAsync.js
var http = require('http');
var app = (function () {
// Private variables...
var responsesRemaining,
urls = [],
responses = [];
var displayResponses = function() {
for(var iterator in responses) {
console.log(responses[iterator]);
}
};
// Public scope...
var pub = {};
pub.main = function (args) {
responsesRemaining = args.length - 2;
// For every argument, push a URL and prep a response.
for(var i = 2; i < args.length; i++) {
urls.push(args[i]);
responses.push('');
}
// For every URL, set off an async request.
for(var iterator in urls) {
var i = iterator;
var url = urls[i];
http.get(url, function(response) {
response.setEncoding('utf8');
response.on('data', function(data) {
if(response.headers.host == url)
responses[i] += data;
});
response.on('end', function() {
if(--responsesRemaining == 0)
displayResponses();
});
});
}
};
return pub;
})();
app.main(process.argv);
Question: What am I doing wrong?
This line
for(var iterator in urls) {
doesn't do what you think it does. It actually loops over the properties of urls (see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in). Instead, you have to do something like
for(var i = 0; i < urls.length; i++) {
var url = urls[i];
...
}
or
urls.forEach(function(url, index) {
...
});
In addition to not properly looping through the arrays inside the app module, I was also not properly concatenating data returned from the response.on('data') event. Originally I was doing...
responses[index] += data;
Instead, the correct thing to do was:
responses[index] = responses[index] + data;
Changing that, as well as the things noted by #arghbleargh got the 'Async Juggling' to fully verify!
I have tested my code and it all worked:
~ $ node juggling_async.js site1 site2 site3 site4 ...
The JS code does not limit only to three sites.
var http = require('http');
// Process all the site-names from the arguments and store them in sites[].
// This way does not limit the count to only 3 sites.
var sites = [];
(function loadSites() {
for(var i = 2, len = process.argv.length; i < len; ++i) {
var site = process.argv[i];
if(site.substr(0, 6) != 'http://') site = 'http://' + site;
sites.push(site);
}
})();
var home_pages = [];
var count = 0;
function httpGet(index) {
var home_page = '';
var site = sites[index];
http.get(site, function(res) {
res.setEncoding('utf8');
res.on('data', function(data) {
home_page += data;
});
res.on('end', function() {
++count;
home_pages[index] = home_page;
if(count == sites.length) {
// Yahoo! We have reached the last one.
for(var i = 0; i < sites.length; ++i) {
console.log('\n############ Site #' + (+i+1) + ': ' + sites[i]);
console.log(home_pages[i]);
console.log('============================================\n');
}
}
});
})
.on('error', function(e) {
console.log('Error at loop index ' + inddex + ': ' + e.message);
})
;
}
for(var i = 0; i < sites.length; ++i) {
httpGet(i);
}

Categories

Resources