How do I prompt users for input in NodeJS [duplicate] - node.js

This question already has answers here:
Get user input through Node.js console
(6 answers)
Closed last month.
I am trying to make a cmd line based program but after realizing chalk uses module type, not the old const module = require('module'); method, I realized I needed a new package for prompting users. How can I easily prompt the user for input in an easy way.

You can use readline built-in module
const readline = require('readline').createInterface({
input: process.stdin,
output: process.stdout,
});
readline.question(`What's your name?`, name => {
console.log(`Hi ${name}!`);
readline.close();
});

Related

How to get variable from input NodeJs

I want to get a value from input
const readline = require('node:readline/promises').createInterface({
input: process.stdin,
output: process.stdout
})
const value = await readline.question('enter :');
console.log(value)
readline.close()
And then I get an Error "SyntaxError: await is only valid in async functions and the top level bodies of modules"
On the other hand in the docs example:
import * as readline from 'node:readline/promises';
import { stdin as input, stdout as output } from 'process';
const rl = readline.createInterface({ input, output });
const answer = await rl.question(
'What do you think of Node.js? '
);
console.log(
`Thank you for your valuable feedback: ${answer}`
);
rl.close();
I copy this example and get the same error. I cant use readline synchronously. I want input a value, some variable will equals this value, and THEN it will console.log(). I dont want to use "Prompt" module. TY
Your issue is because you are trying to use top-level-await.
Now this is possible in modern nodejs (16+ I think), but you need to tell explicitly node to use modules, like your in your second code.
Try to upgrade nodeJS to the latest version 18, it should run fine.
(Also you may need to hint node on using modules explicitly, for that either name your file using the extension .mjs or specify "type": "module" in your package.json
Working example using .mjs and current node v18.6 the code is copy pasted from your question, no changes made.

TypeError: readline.createInterface is not a function

I am trying to read input from console using Node.
I installed readline-promise:
npm install readline-promise
and it is correctly installed in node_modules.
Code:
import readline from "readline-promise";
const rlp = readline.createInterface({
input: process.stdin,
output: process.stdout,
terminal: true,
});
And I get the following error:
TypeError: readline.createInterface is not a function
For reasons I don't understand, the readline-promise module does not seem to work the way its documentation says it should when importing from an ESM module using import.
The default export is not working properly the way the doc shows so it appears you have to manually get the right entry points.
After examining the object you get when you import readline-promise, this is what I was able to get to work:
import rl from "readline-promise";
const readline = rl.default;
const rlp = readline.createInterface({
input: process.stdin,
output: process.stdout,
terminal: true,
});

Node.js readline module: stop reprinting the line just read

I'm using the readline module in Node (12) to accept user input as such:
import * as readline from "readline";
process.stdin.setEncoding('utf-8');
console.log("input is a TTY?",process.stdin.isTTY);
const rl = readline.createInterface({input: process.stdin, output: process.stdout, prompt: '> '});
rl.prompt();
rl.on('line' ,inputLine => { inputStringLines.push(inputLine); rl.prompt(); });
rl.on('close',() => { console.log('input has closed'); main(); });
The lines are correctly captured into my inputStringLines array but annoyingly, the process is printing out every line just read:
How can I get rid of the extra lines (the ones without the > prompt)
I fixed it by changing how run my script. Before, I used nodemon with node's -r ts-node/register option. The issue went away when I switched to using ts-node-dev to execute the script.
Note also that process.stdin.isTTY is now correctly set whereas it was undefined before (look at the first line in the image below, vs in the original post)
Still don't know the root cause, but I'm happy to move on.

Is it possible to push text to prompt input?

I am using the prompt module, node version 12.4.0
I am wondering if its possible to push a string to the 'input field' of a prompt.get()
The following script displays a (double) "prompt: "
After 5 seconds, it inserts the text "This is a test"
When an enter command is given, the string is not recognized as input.
It isn't possible to edit the string before pressing enter either.
(type anything before 5 sec and press enter, and the input WILL display)
End-goal: to have commands send to prompt from external source, but give the end user the ability to modify the commands before entering.
I tried process.stdout.write, process.stdin.write
I also tried to replace process.std*.write with prompt.std*.write
The answer might be os-specific, but I have tried this code both under Win10 x64 as well as Linux
const prompt = require("prompt");
function myFunc() {
process.stdin.write("This is a test");
}
setTimeout(myFunc, 5000);
prompt.get({
properties: {
test: {
description: "prompt"
}
}
}, (err, result)=> {
console.log("input: "+ result.test);
});
actual result:
~/Nodejs/temp$ node index.js
prompt: prompt: This is a test
input:
~/Nodejs/temp$
desired result:
~/Nodejs/temp$ node index.js
prompt: prompt: This is a test
input: This is a test
~/Nodejs/temp$
After digging into how the prompt module works, I 'solved' this myself.
prompt uses readline behind the curtains, and readline has a .write function that does what I need, send editable text to the prompt.
prompt itself does not extend this function, and since it hasnt been maintained for 3 years, I switched to readline instead.
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
prompt: 'prompt> '
});
rl.prompt();
rl.on('line', (line) => {
console.log(line);
rl.prompt();
}).on('close', () => {
console.log('Have a great day!');
process.exit(0);
});
// simulate external input, and write to prompt>
function myFunc() {
rl.write("This is a test");
}
setTimeout(myFunc, 5000);

Prompt module in NodeJS repeating the input

I'm making an application using NodeJS and its a CLI application; to get the input from the user, I'm using the "prompt" module. I can use it, but while typing in the prompt's prompt, each character is getting repeated, however the output is fine! The code is below. Please Help.
prompt.start();
prompt.get({
properties: {
name: {
description: "What is your name?".magenta
}
}
}, function (err, result) {
console.log("You said your name is: ".cyan + result.name.cyan);
});
IMAGE:
Before using the "prompt" module, I used the ReadLine interface; sadly I had the same problem. However, the fix was simple:
Remove the rli.close(); and then run it.
Then re-add the rli.close(); and it works!
Thanks mscdex for the input, though :)
FWIW if you just need simple prompting, you can use the built-in readline module's question() method (which does not exhibit the double output issue). Example:
var readline = require('readline');
var rli = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rli.question('What is your name? ', function(answer) {
console.log('You said your name is: ' + answer);
rli.close();
});

Resources