19

I am writing a program which will create an array of numbers, and double the content of each array, and storing the result as key/value pair. Earlier, I had hardcoded the array, so everything was fine.

Now, I have changed the logic a bit, I want to take the input from users and then, store the value in an array.

My problem is that I am not able to figure out, how to do this using node.js. I have installed the prompt module using npm install prompt, and also, have gone through the documentation, but nothing is working.

I know that I am making a small mistake here.

Here's my code:

//Javascript program to read the content of array of numbers
//Double each element
//Storing the value in an object as key/value pair.

//var Num=[2,10,30,50,100]; //Array initialization

var Num = new Array();
var i;
var obj = {}; //Object initialization

function my_arr(N) { return N;} //Reads the contents of array


function doubling(N_doubled) //Doubles the content of array
{
   doubled_number = my_arr(N_doubled);   
   return doubled_number * 2;
}   

//outside function call
var prompt = require('prompt');

prompt.start();

while(i!== "QUIT")
{
    i = require('prompt');
    Num.push(i);
}
console.log(Num);

for(var i=0; i< Num.length; i++)
 {
    var original_value = my_arr(Num[i]); //storing the original values of array
    var doubled_value = doubling(Num[i]); //storing the content multiplied by two
    obj[original_value] = doubled_value; //object mapping
}

console.log(obj); //printing the final result as key/value pair

Kindly help me in this, Thanks.

vamosrafa
  • 685
  • 5
  • 11
  • 35

4 Answers4

46

For those that do not want to import yet another module you can use the standard nodejs process.

function prompt(question, callback) {
    var stdin = process.stdin,
        stdout = process.stdout;

    stdin.resume();
    stdout.write(question);

    stdin.once('data', function (data) {
        callback(data.toString().trim());
    });
}

Use case

prompt('Whats your name?', function (input) {
    console.log(input);
    process.exit();
});
Rick
  • 12,606
  • 2
  • 43
  • 41
  • Excellent, much more lightweight than bringing in prompt and its dependencies – Clint Mar 26 '17 at 04:03
  • Is ``stdin.resume();`` necessary? I'm new to this, but reading the docs on readable streams and it says setting the 'data' event handler takes it out automatically (c.f. https://nodejs.org/api/stream.html#stream_readable_streams) – labyrinth Jun 14 '17 at 21:31
  • 1
    @JECompton it might not be necessary but I’d do it, because you may [`stdin.pause()`](https://nodejs.org/api/stream.html#stream_readable_pause) somewhere else, to e.g. allow Node to exit cleanly after a prompt, and you’ll need to `resume` it for this to work. See my little example: https://gist.github.com/fasiha/8ee923fd1a27d596af1d287785465231 – Ahmed Fasih Jul 06 '17 at 00:55
  • It's great to have something without a dependency. Much appreciated. – Can Jan 05 '20 at 16:36
22

Modern Node.js Example w/ ES6 Promises & no third-party libraries.

Rick has provided a great starting point, but here is a more complete example of how one prompt question after question and be able to reference those answers later. Since reading/writing is asynchronous, promises/callbacks are the only way to code such a flow in JavaScript.

const { stdin, stdout } = process;

function prompt(question) {
  return new Promise((resolve, reject) => {
    stdin.resume();
    stdout.write(question);

    stdin.on('data', data => resolve(data.toString().trim()));
    stdin.on('error', err => reject(err));
  });
}


async function main() {
  try {
    const name = await prompt("What's your name? ")
    const age = await prompt("What's your age? ");
    const email = await prompt("What's your email address? ");
    const user = { name, age, email };
    console.log(user);
    stdin.pause();
  } catch(error) {
    console.log("There's an error!");
    console.log(error);
  }
  process.exit();
}

main();

Then again, if you're building a massive command line application or want to quickly get up and running, definitely look into libraries such as inquirer.js and readlineSync which are powerful, tested options.

Govind Rai
  • 14,406
  • 9
  • 72
  • 83
10

Prompt is asynchronous, so you have to use it asynchronously.

var prompt = require('prompt')
    , arr = [];

function getAnother() {
    prompt.get('number', function(err, result) {
        if (err) done();
        else {
            arr.push(parseInt(result.number, 10));
            getAnother();
        }
    })
}

function done() {
    console.log(arr);
}


prompt.start();
getAnother();

This will push numbers to arr until you press Ctrl+C, at which point done will be called.

josh3736
  • 139,160
  • 33
  • 216
  • 263
5

Node.js has implemented a simple readline module that does it asynchronously:

https://nodejs.org/api/readline.html

const readline = require('readline');

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

rl.question('What do you think of Node.js? ', (answer) => {
  // TODO: Log the answer in a database
  console.log(`Thank you for your valuable feedback: ${answer}`);

  rl.close();
});
Shay
  • 2,060
  • 2
  • 16
  • 22