Process Object Stdout and StdIn do not work as expected - node.js

I am using vsCode for NodeJS.
My code was simple. So I was expecting stdout should wait for input from console. Once input is given, then it should go to exit.
But once i do > node process
the program goes to exit directly.
file - process.js ->
process.stdout.write('Ask me something : ');
process.stdin.on('data', function(answer){
console.log(answer.toString());
});
console.log('exit')
process.exit();
Output:
c:\node-projects\demo-nodejs>node process
Ask me something : exit
c:\node-projects\demo-nodejs>
How can I use process object to get standard input/output/print/exit the code instead of using other readline object?

There are a few question/answers such as this one already on this site that probably answer what you are asking. Your code is not working because the line with process.stdin.on is not a synchronous callback method call, it is an event handler that waits for the 'data' event.
If I understand what you are trying to do, I think it is easiest to import the 'readline' module. It is built-in to the nodejs executable, but not loaded to your code execution environment unless you require it.
That would make your code look like this:
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question('Ask me something : ', function(answer){
console.log(answer.toString());
console.log('exit')
process.exit();
});
Note that the rl.question method call executes right away and calls the function(answer) function when the user is done with text input. It can take some understanding and getting used to the asynchronous program control flow in NodeJS, you might have to rethink some of the rest of your program structure.
The offical documentation for the readline NodeJS module and function is here.

Related

What does the additional JavaScript mean in node document?

Blocking is when the execution of additional JavaScript in the Node.js process must wait until a non-JavaScript operation completes. This happens because the event loop is unable to continue running JavaScript while a blocking operation is occurring.
It means the rest of your JavaScript code, that hasn't been excuted yet. It's blocked from being excuted, until non-JavaScript operation completes.
They explain it in the next section in the documentation: https://nodejs.org/en/docs/guides/blocking-vs-non-blocking/#comparing-code
In the first example:
const fs = require('fs');
const data = fs.readFileSync('/file.md'); // blocks here until file is read
console.log(data);
moreWork(); // will run after console.log
The additional JavaScript code here is the 2 lines that are blocked by the synchronous file reading, above it. These 2 lines don't get excuted until the file reading is complete:
console.log(data);
moreWork(); // will run after console.log
Tip: when you ask a question, it's best to add sources if your question references another website. In this case: https://nodejs.org/en/docs/guides/blocking-vs-non-blocking/#blocking

Electron Readline

I'm trying to build an app using electron, it's designed to get a GUI later but for now i'm just trying to do this:
function test(){
console.log("In Test")
var readline = require('readline');
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.on('line', function(line){
console.log(line);
})
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
app.on('ready', test);
On launching npm start, I see the "In Test" log, but when I type something in my shell, it's not returned to me as I need it to be by the Readline module.
Am I missing something ?
In Electron the console becomes the Chromium console which is not like the terminal you're used to. Readline is not going to work as far as I know. The blink console in Chromium does not support reading input this way. It operates more like a debug REPL where you can type JS code, inspect variables, etc. It's not for user input. I don't think you're going to be able to get input supplied from that console into stdin, which is where the readline module is waiting to see data.
Update
I assumed OP was using the dev tools console expecting it to work like a shell. He was using it properly. The actual issue is a bug with node's readline module on Windows. Node devs are actively working to fix it. It's a regression bug that was fixed once before but appeared again in recent versions of node.

Output being written to process.stdout twice

I want to pass a message from a nodejs script to chrome extension using nativeMessaging and thus am using the chrome-native-messaging node module in the following way to pass a message to stdout.
var rs = new stream.Transform({objectMode: true});
var msg = {"message":"pingfromelectron"};
rs.push(msg);
rs.pipe(output).pipe(process.stdout);
However, this is writing the output twice to stdout as you can see in the screenshot below:
I am not quite sure why this is happening. Any pointers would be helpful.

node.js STDIN works with process.stdin, not when piped

I'm using require("child_process").spawn and calling an executable, which at the beginning is pausing for a password to be input; if I use it like below:
var spawn = require("child_process").spawn;
var exe = spawn("NameOfExe.exe", [/*arguments*/], {stdio: [process.stdin, process.stdout, process.stderr]});
It works perfectly (Yes, I know I can do inherit, shush :p ). I can type inside my console and it'll accept it with no issues.
However, if I do it like this:
var spawn = require("child_process").spawn;
var exe = spawn("NameOfExe.exe", [/*arguments*/], {stdio: ["pipe", process.stdout, process.stderr]});
exe.stdin.write("Password\n");
then the executable doesn't even receive the stdin; it immediately goes to Execution Failed.
I'm completely at a loss for this. Any suggestions?
EDIT:
I think I may be onto something!
So I'm 99.99% certain that the executable is using C# and Console.ReadKey to get the password. However, according to Microsoft, an exception gets thrown whenever the In property is redirected somewhere else.
So this explains it, but is there a way around this using Node, or am I at the mercy of the people who made this executable?
The ReadKey method reads from the keyboard even if the standard input is redirected to a file with the SetIn method.
You figured it out. It uses native bindings to the hardware controller/HAL, and not the shell, to handle stdio.

Node.js "on" function - What does it do?

var rd = readline.createInterface({
input: fs.createReadStream(file),
output: process.stdout,
terminal: false
});
rd.on('line', function(line) {
And is any way how to make "on" working synchronous. Code inside "on" loop need to be done before executing loop again. Is any way how to do that?
Generally, the on function registers an event handler for a specific event.
The readline::line event serves for this purpose:
Emitted whenever the input stream receives a \n, usually received when
the user hits enter, or return. This is a good hook to listen for user
input.
— NodeJS documentation
By the way, which keywords did you use for your search? I used nodejs readline.createInterface and the first result was this NodeJS documentation page!

Resources