1

I am constructing a Yahtzee in node.js. I use below code to ask user for input. The answer needs to be stored in a variable. I assume [answer] is used to temporarily store the answer value, but how can I get out the [answer] to an array without to many change of the code structure ?

Basic code structure:

const readline = require('readline');

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

rl.question("Which dices to keep [1,2,3,4,5] ?: ", (answer) => {
  console.log("Will keep dices: ", answer);
  rl.close();
});

Extended basic code structure, to add the user input answer, into a variable:

var lines;                                 // Added compared to basic code.
const readline = require('readline');
const rl = readline.createInterface({
  input:  process.stdin,
  output: process.stdout
});
rl.question("Which dices to keep [1,2,3,4,5] ?: ", (answer) => {
  lines.push(answer);                      // Added compared to basic code.
  console.log("Will keep dices: ", answer);
  rl.close();
});
console.log(lines);                        // Added compared to basic code.

Result from terminal: Undefined.

Toolbox
  • 2,333
  • 12
  • 26

1 Answers1

3

That's not really how this works - with asynchronous operations like user input, it's expected that you will handle the outcome in a callback, rather than "waiting" for completion. One thing you can do is wrap your code in a Promise, like this:

const readline = require('readline');

function getDiceAnswer() {
    return new Promise(resolve => {    
        const rl = readline.createInterface({
            input:  process.stdin,
            output: process.stdout
        });
        rl.question("Which dices to keep [1,2,3,4,5] ?: ", (answer) => {
            resolve(answer);
            console.log("Will keep dices: ", answer);
            rl.close();
        });
    });   
}

This still means you need to deal with a result in a callback:

const lines = [];
getDiceAnswer().then(answer => {
     lines.push(answer);
     console.log(lines);
});

...but you can use Javascript async/await notation to make it look nicer:

async function getAnswers() {
     const diceAnswer = await getDiceAnswer();

     //this line won't execute until the answer is ready
     lines.push(diceAnswer);
}

Another, simple alternative is to use a pacakge like readline-sync to make the action a synchronous one: https://www.npmjs.com/package/readline-sync

Duncan Thacker
  • 5,073
  • 1
  • 10
  • 20