4

I am creating a module to get experience and shorten some code. I have a piece of code which uses readline in a simplified manner, like var x = arkin.question("How old are you? ");. Readline doesn't wait for the answer. It produces this:

How old are you? undefined

Code:

const readline = require('readline');

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

exports.question = function(q){

  var response;

  rl.setPrompt(q);
  rl.prompt();
  rl.on('line', (userInput) => {
    response = userInput;
    rl.close();
  });

  rl.on('close', () => {
    return response;
  });
}

I call it like this:

var age = arkin.question("How old are you? ");
console.log(age);

I have tried using this code:

rl.question(q, (userInput) => {
    rl.close;
    response = userInput;
    return response;
});

Yet I get the same result. Thanks in advance for your help.

Arkin Solomon
  • 592
  • 1
  • 5
  • 23

2 Answers2

9

whenever you call arki.question it registeres the event listeners .on("line") and .on("close") then returns from the function. Whatever you returning from .on("close") event listener question function does not know about it, because it is no longer on the call stack. you can either use a callback or promises with async...await to get your result.

with callbacks

const readline = require('readline');

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

exports.question = function(q , cb ){

    var response;

    rl.setPrompt(q);
    rl.prompt();

    rl.on('line', (userInput) => {
        response = userInput;
        rl.close();
    });

    rl.on('close', () => {
        return cb(response);
    });
};

you call it like this

var age  = arki.question("how old are you? ", resp => {
    console.log(resp);
});

with promises

const readline = require('readline');

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

exports.question = function(q){

    var response;

    rl.setPrompt(q);
    rl.prompt();

    return new Promise(( resolve , reject) => {

        rl.on('line', (userInput) => {
            response = userInput;
            rl.close();
        });

        rl.on('close', () => {
            resolve(response);
        });

    });


};

you call it like this

arki.question("how old are you? ").then( response => console.log(response) );

or

; ( async () => {
    console.log(await arki.question("how old are you? "));
})();
0.sh
  • 2,659
  • 16
  • 37
  • Ok, now i understand, but doing this is just as complex as using it normally. Thanks for your help! – Arkin Solomon Dec 30 '18 at 21:56
  • you should put const r1 = readline.createInterface(...) within the question function otherwise it only works the first time. – bruceceng Nov 18 '20 at 23:16
0
//global stuff, where we import readline. 
//But avoid assigning global vars.
    var age;
    var readline = require('readline'), menu;
        
//define function
    function whatever() = {
    
//create readline instance and assign it to menu
    menu = readline.createInterface({
        input: process.stdin,
        output: process.stdout
    });
        
//Use the readline.question method, which is what you're looking for.
//It requires a callback function with a variable for the users input.
    menu.question('How old are you? ', function(input) {
        age = input;
    });
        
    console.log(`You are ${age} years old.`);
}
        
//Tell node to run the program
whatever();