Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wait for user input from readline module (Node.Js)

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.

like image 477
Arkin Solomon Avatar asked Mar 05 '23 19:03

Arkin Solomon


1 Answers

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? "));
})();
like image 83
0.sh Avatar answered Mar 16 '23 10:03

0.sh