Node JS not able to trigger end usinf stdin - javascript

I am using NodeJS version v6.9.4. I am trying to execute the below sample code. It continuously but not ending the program. Can anyone help me solve my problem.
var stdin = process.stdin,
stdout = process.stdout,
inputChunks = [];
#stdin.resume();
stdin.setEncoding('ascii');
stdin.on('data', function (chunk) {
inputChunks.push(chunk);
});
stdin.on('end', function () {
var inputJSON = inputChunks.join(),
parsedData = JSON.parse(inputJSON),
outputJSON = JSON.stringify(parsedData, null, ' ');
stdout.write(outputJSON);
stdout.write('\n');
});

Related

Taking simple shell input with javascript

I'm trying to take simple input from a linux shell when a javascript program is run. I've tried using readline() and prompt() but both of those throw Reference Error: readline() is not defined or prompt() is not defined.
//Decode Bluetooth Packets
var advlib = require('advlib');
console.log("What data to process - If you respond N than what is written inline will be decoded");
var input = require();
if (input != "N") {
var rawHexPacket = input
var processedpacket = advlib.ble.process(rawHexPacket);
console.log(JSON.stringify(processedpacket,null, " "));
}
else {
//Put in raw data here!
var rawHexPacket = 'dfasdfasdfasd4654df3asd3fa3s5d4f65a4sdf64asdf';
var processedpacket = advlib.ble.process(rawHexPacket);
console.log(JSON.stringify(processedpacket,null, " "));
}
So what is a simple way to get javascript input through a linux shell?
I used the link posted and turned it into this (which works):
var advlib = require('advlib');
var readline = require('readline');
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
try {
rl.question("What data to process - If you respond N then what is written inline will be decoded. ", function(answer) {
console.log("You said: ",answer);
if (answer != "N") {
var rawHexPacket = answer
var processedpacket = advlib.ble.process(rawHexPacket);
console.log(JSON.stringify(processedpacket,null, " "));
}
else {
//Put in raw data here!
var rawHexPacket = '';
var processedpacket = advlib.ble.process(rawHexPacket);
console.log(JSON.stringify(processedpacket,null, " "));
}
});
}
catch(err) {
console.log("Somthing went wrong - was your input valid?");
};

Array is empty after readline data is pushed

I am trying to write a program, where I need to read data from a file line by line synchronously, store values line by line in an array using Array.push(). I am reading the file using the readline npm package. However, when I try to call the array after iterating through the whole file, it shows me an empty array.
var fs = require('fs'),
readline = require('readline'),
stream = require('stream');
var instream = fs.createReadStream('sample.txt');
var outstream = new stream;
outstream.readable = true;
outstream.writable = true;
function printArray(ArrayVar){
console.log(ArrayVar);
}
function AddText(InputStream){
var Text = new Array;
var rl = readline.createInterface({
input: instream,
output: outstream,
terminal: false
});
rl.on('line',function(line){
Text.push(line);
});
return Text;
}
var a = AddText(instream);
printArray(a);
I think I am having a problem because of the asynchronous execution of this code. How can I fix this and print the content of the array in proper order as in the text file?
You need to listen to the close event and then print the array. close will be called once all lines have been read.
rl.on('close', function() {
console.log(Text)
});
Also,
var Text = new Array;
Should be:
var Text = new Array();
or
var Text = [];
You have to wait for the lines to be read before logging the variable(in your case its Text) value.
You must wait for all the lines to be read by listening on close event, or do something in line event itself.
Your code should look something like below
var fs = require('fs'),
readline = require('readline'),
stream = require('stream');
var instream = fs.createReadStream('sample.txt');
var outstream = new stream;
outstream.readable = true;
outstream.writable = true;
function printArray(ArrayVar){
console.log(ArrayVar);
}
function AddText(InputStream){
var Text = new Array;
var rl = readline.createInterface({
input: instream,
output: outstream,
terminal: false
});
rl.on('line',function(line){
Text.push(line);
});
rl.on('close', function(){
printArray(Text)
})
}
var a = AddText(instream);
Also you are not using the parameter InputStream that you are passing to AddText function.

Can someone help me with this syntax?

This maybe silly but I'm unfamiliar with the syntax here:
var stdin = '';
process.stdin.on('data', function (chunk) {
stdin += chunk;
}).on('end', function() {
var lines = stdin.split('\n');
for(var i=0; i<lines.length; i++) {
process.stdout.write(lines[i]);
}
});
I'm supposed to write a program that squares a number, which I know how to do, but I've never encountered this type of structure. I understand the loop and that process.stdout.write is essentially console.log The test cases inputs are 5 and 25. Outputs should be 25 and 625.
Where am I supposed to write the code to do this?
You can put it in a file sample.js and run it:
node sample.js
This process.stdin refers to the stdin stream (incoming data from other applications, for example, a shell input , so basically this:
process.stdin.on('data', function (chunk) {
stdin += chunk;
})
says, whenever there new data (user typed in something into a console, hosting application send some data), read it and store it in stdin variable. Then, when the stdin stream is over (for example, a user finished entering data):
.on('end', function() {
var lines = stdin.split('\n');
for(var i=0; i<lines.length; i++) {
process.stdout.write(lines[i]);
}
})
the code outputs back what a user typed in.
It appears all of the infrastructure is there. All that's left is actually squaring your numbers.
process.stdin and process.stdout are node streams which are asynchronous and so use events to tell you what's going on with them. data is the event for when there is data ready to process and end is for when there's no more data. The code just snarfs process.stdin and then, once the data is all in memory, processes it.
The end anonymous function would probably be best implemented like this:
function() {
stdin.split('\n').foreach(function(line){
var value = line.trim()|0;
process.stdout.write(value * value);
});
}
Off topic: The memory footprint might be improved by processing the stream as it comes in rather than collecting it and then processing it all at once. This depends on the sizes of the input and the input buffer:
var buffer = '';
var outputSquare = function(line) {
var value = line.trim()|0;
process.stdout.write(value * value);
};
process.stdin.on('data', function (chunk) {
var lines = (buffer + chunk).split('\n');
buffer = lines.pop();
lines.foreach(outputSquare);
}).on('end', function() {
outputSquare(buffer);
});
process.stdin.resume();
process.stdin.setEncoding('utf8');
const squareNum = (num) => (num ** 2);
let stdin = '';
process.stdin.on('data', (chunk) => {
stdin = `${stdin}${chunk}`;
console.log(squareNum(parseInt(chunk)));
}).on('end', () => {
//const lines = stdin.trim().split('\n');
//for (const line of lines) {
// process.stdout.write(`${line}\n`);
//}
});

nodejs createReadStream start from nth line

I have the following code in order to read a text file line by line with nodejs:
var lineReader = require('readline').createInterface({
input: require('fs').createReadStream('log.txt')
});
lineReader.on('line', function (line) {
console.log(line);
});
lineReader.on('close', function() {
console.log('Finished!');
});
Is there any way to start reading the file from a specific line?
According to the Node.js Docs you can specify both start and end options when creating the stream:
options can include start and end values to read a range of bytes from the file instead of the entire file. Both start and end are inclusive and start at 0
// get file size in bytes
var fileLength = fs.statSync('log.txt')['size'];
var lineReader = require('readline').createInterface({
input: require('fs').createReadStream('log.txt', {
// read the whole file skipping over the first 11 bytes
start: 10
end: fileLength - 1
})
});
A solution i found,
var fs = require('fs');
var split = require('split');
var through = require('through2');
fs.createReadStream('./index.js')
.pipe(split(/(\r?\n)/))
.pipe(startAt(5))
.pipe(process.stdout);
function startAt (nthLine) {
var i = 0;
nthLine = nthLine || 0;
var stream = through(function (chunk, enc, next) {
if (i>=nthLine) this.push(chunk);
if (chunk.toString().match(/(\r?\n)/)) i++;
next();
})
return stream;
}
See
split: https://github.com/dominictarr/split
through2: https://github.com/rvagg/through2

process.stdout.write() not working in Node.js readline CLI program

I am using the readline module to create a command line interface (CLI) for an application in Node.js.
The problem is that I can not scroll up to view the past commands as I usually can in Terminal. My CLI is just a fixed window and if I print too much out to the screen, I lose information at the top and there is no way to scroll up to see it.
(I am running my program on Mac OSX Mavericks)
Thanks in advance.
Code Snippet:
var readline = require('readline');
var Cli = function () {
this.txtI = process.stdin;
this.txtO = process.stdout;
process.stdout.write('CLI initialized.');
this.rl = readline.createInterface({input: this.txtI, output: this.txtO });
this.rl.setPrompt('>>>');
this.rl.prompt();
this.rl.on('line', function(line) {
var input = line.toString().trim();
if (input) {
this.txtO.write('cmd: ' + input);
}
this.rl.prompt();
}.bind(this)).on('close', function() {
this.txtO.write('Have a great day!');
process.exit(0);
}.bind(this));
};
new Cli();
Save this file as snippet.js and run
node snippet.js
in terminal.
It probably is working, just readline is overwriting your line. Try outputting multiple lines:
process.stdout.write("1\n2\n3\n4\n5");
Readline is quite an awesome module. History is already there. As is the possibility to add completion. Try the snippet below.
var readline = require('readline');
function createCLI(opt) {
var rl = readline.createInterface({
input : opt.input,
output : opt.output,
terminal : opt.terminal || true,
completer : opt.completer ||
function asyncCompleter(linePartial, callback){
var completion = linePartial.split(/[ ]+/);
callback(null, [completion, linePartial]);
}
});
rl.on('line', function(line) {
if( !line.trim() ){ this.prompt(); }
else { this.write(line); }
}).on('close', function() {
this.output.write('\n Have a great day!');
process.exit(0);
}).setPrompt(' > ');
rl.output.write(' CLI initialized\n');
return rl;
}
var cli = createCLI({
input : process.stdin,
output : process.stdout
});
cli.prompt();

Categories