NodeJs keystrokes get printed twice in console [duplicate] - node.js

This question already has answers here:
Get user input through Node.js console
(6 answers)
Closed last month.
I'm new to NodeJs and i'm used to C# were we can use
Console.ReadLine();
I looked into 'readline' and the node prompt package, but it either outputs all the user input twice while entering or, with the 'terminal: false' option, does not allow us to use the backspace.

var stdin = process.openStdin();
stdin.addListener("data", function(d) {
console.log("your input: " + d.toString());
});
This is like you take input value

There is a readline, you can use it like this:
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question('How are you today? ', (answer) => {
// TODO: Log the answer in a database
console.log(`Thank you for your valuable feedback: ${answer}`);
rl.close();
});
Documentation is available here.

Related

Is there a way to clear readline prompt line?

I've been looking around everywhere and I was still unable to find an answer.
I have an example program here which requests input with readline and then logs something after the input was entered.
Here is an extremely basic example:
const readline = require("readline");
const rl = readline.createInterface(process.stdin, process.stdout);
rl.question("What is your name? ", function(res) {
console.log("Hey, your name is", res);
rl.close();
});
What I want to do is completely hide What is your name? (name) after enter was pressed and only show Hey, your name is .... It seems like such a basic thing but after hours of research I failed to find a solution.
I have tried process.stdout.clearLine() but since enter makes a new line, it clears that new line instead which keeps the input. I have also tried appending \r to the end of the input but since enter creates a new line, the same happens as with clearLine.
This can be done by using the readline.moveCursor and readline.clearScreenDown methods.
const readline = require("readline");
const rl = readline.createInterface(process.stdin, process.stdout);
console.log("Hello there (dont delete this)");
rl.question("What is your name? ", function(res) {
// moves up 3 lines (question + answer + enter new line)
readline.moveCursor(process.stdout,0,-3);
readline.clearScreenDown(process.stdout);
console.log("Hey, your name is", res);
rl.close();
});
Example REPL
You may need to perform some math if the question or response contains new lines.

Readline works only for the first time

I'm using Node's readline but it works only for the first time.
At the first try everything works well (answer is logged and readline is closed) but another time it looks like the readline is not being closed (answer is never logged and console is still waiting for my input even if I've already sent it).
I've class in Node.js (using ES6 with Babel and Nodemon) which has readline in constructor.
class SomeClass
{
constructor(readline) {
this.readline = readline;
}
askPath() {
this.readline.question('Question: ', (answer) => {
console.log(answer);
this.readline.close();
this.askPath();
});
}
}
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
let someClass = new SomeClass(rl);
someClass.askPath();
Console looks like:
> Question: answer
> answer
> Question: second answer
> I can still write
> nothing happens...
Just don't call the .close() function, inside of your callback as it closes the entire readline interface
askPath() {
this.readline.question('Question: ', (answer) => {
console.log(answer);
this.askPath();
});
}
As the documentation says:
The rl.close() method closes the readline.Interface instance and relinquishes control over the input and output streams. [source:nodejs.org]

user input with node.js

I have the following Node.js code that behaves strangely:
#!/usr/bin/env node
"use strict";
var readline = require('readline');
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
function input(prompt) {
rl.question(prompt, function (x) {
rl.close();
console.log("debug: " + x);
return x;
});
}
function main() {
var n = input("Number: ");
// console.log("value: " + n); // problematic line
}
main();
I want to mimic Python's raw_input, i.e. reading a line from the user. After showing the prompt, the program should be blocked until the user presses Enter.
If the "problematic line" is in comments, it works, the program is waiting for input. However, if this line is not in comments, then the program doesn't wait for input and n becomes undefined. Why? How to write a function that returns the user input?
That's because you are expecting the execution of input wait until return is called, which is not how this will work. The problematic line is indeed the previous one. First, input does not return anything, the return statement is the return of the question callback function, but then, you seem to misunderstand the execution flow, as we all have at some point (you'll get it pretty quick after some dead-ends like this one)
Your script is loaded
You declare and define rl, input and main
Main executes
You define n as the result of input
And here is where things start getting asynchronously funny
since question is asynchronous, its execution start but does not block the process
input returns undefined (while you're still waiting for the input)
you print that undefined
You write something on the input
question() finishes its execution and calls the callback (the function you gave as second parameter)
rl is closed
the callback function returns the line, and it is swallowed by the void (this is not technical terminology, just a metaphor)
You may want to do it like this:
#!/usr/bin/env node
"use strict";
var readline = require('readline');
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
function input(prompt, callback) {
rl.question(prompt, function (x) {
rl.close();
callback(x);
});
}
function main() {
var n = input("Number: ", console.log);
}
main();
If you're new to javascript and node, you may find very useful to use learnyounode and the node code school path or even, if you have the time, the money and the opportunity, read Node.js, MongoDB, and AngularJS Web Development, by Brad Dayley.

Is there a way to get synchronous terminal input in Node.js

I have looked at similar questions on SO and I have an ongoing question about if it is possible to get synchronous input from the command line.
I know about readline and process.stdin.on('readable', ...) but both of those seem to be asynchronous.
I am looking to for a way to prompt the user for input where code later on in my script does not run before there is user input.
May be you can try this in case if you know fix number of inputs you want in sync manner.
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
let i = 0;
rl.question('Number of inputs : ', (answer1) => {
rl.on('line', (answer2) => {
console.log(`input: ${answer2}`);
i++;
if (i >= answer1) {
rl.close();
}
});
});

NodeJS - standalone application to making user to input data

Does NodeJS has any functionality for accepting input via standard input from a user. In Browser based JS we used to use 'prompt' functionality for same but the this would not work on NodeJS standalone app.
node one.js
Enter any number:
<program accepts the number and does the processing>
As vinayr said, you should use readline. An example of what you desire:
var readline = require('readline');
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question("Input number:", function(numAnswer) {
// TODO: Log the answer in a database
var num = parseInt(numAnswer);
processingFunctionYouUse(num);
rl.close();
});
Use readline prompt http://nodejs.org/api/readline.html
I would like to suggest you to use stdio. It is a module that aims to simplify your life with standard input/output. One of its main features is the standard input reading, line by line, and it can be done as follows:
var stdio = require('stdio');
stdio.readByLines(function (line) {
// This function is called for every line while they are being read
}, function (err) {
// This function is called when the whole input has been processed
});
PD: I'm the stdio creator. :-)
(source: nodei.co)

Resources