Reputation: 17
I have started working with node js and am working with the line-by-line dependency. I have properly installed line-by-line and it is within the folder. Currently, my application will run but will not prompt the user to input an answer. My code is as follows:
var rlname;
var rlage;
var rlcolor;
// Create reading interface
const readline = require('readline');
const rl = readline.createInterface ({
input: process.stdin,
output: process.stdout,
prompt: '>'
});
// Ask a question
function getUserInput()
{
rl.question("What is your name? \n", (name) => {
console.log(name);
rlname = name;
// Log answer in JSON
})
rl.question("What is your age? \n", (age) => {
console.log(age);
rlage = age;
// Log answer in JSON
})
rl.question("What is your favorite color? \n", (color) => {
console.log(color);
rlcolor = color;
// Log answer in JSON
})
console.log("Hello " + rlname + ", you are " + rlage + " years old and your favorite color is " + rlcolor + ".");
}
getUserInput();
rl.close();
This is the produced result:
What is your name?
Hello undefined, you are undefined years old and your favorite color is undefined.
Upvotes: 0
Views: 1382
Reputation: 1407
The problem here is caused by the fact that this code should be asynchronous, but it is written as if it was synchronous.
To be more clear: you ask for the name, but the code is not waiting for the input, as it is asynchronous. It continues down to the console.log statement and proceed to close the input with rl.close()
.
You should put each question inside the callback of the previous one, and the closing statement in the last callback:
var rlname;
var rlage;
var rlcolor;
// Create reading interface
const readline = require('readline');
const rl = readline.createInterface ({
input: process.stdin,
output: process.stdout,
prompt: '>'
});
// Ask a question
function getUserInput()
{
// FIRST QUESTION
rl.question("What is your name? \n", (name) => {
console.log(name);
rlname = name;
// SECOND QUESTION
rl.question("What is your age? \n", (age) => {
console.log(age);
rlage = age;
// THIRD QUESTION
rl.question("What is your favorite color? \n", (color) => {
console.log(color);
rlcolor = color;
// LOG DATA
console.log("Hello " + rlname + ", you are " + rlage + " years old and your favorite color is " + rlcolor + ".");
// CLOSE CONNECTION
rl.close();
})
})
})
}
getUserInput();
Upvotes: 0
Reputation: 2099
Like many modules in Node.js, readline
works on the basis of callbacks. The callback functions you are passing to rl.question
don't run immediately; they are called only when input has been received from the user. So your program is trying to ask three questions all at once and then immediately log your "Hello" line before any of the answers have been received. (You are probably not seeing the second or third question because readline has some internal buffer for them.)
With callbacks, the correct approach is nesting like this:
var rlname;
var rlage;
var rlcolor;
// Create reading interface
const readline = require('readline');
const rl = readline.createInterface ({
input: process.stdin,
output: process.stdout,
prompt: '>'
});
// Ask a question
function getUserInput()
{
rl.question("What is your name? \n", (name) => {
console.log(name);
rlname = name;
rl.question("What is your age? \n", (age) => {
console.log(age);
rlage = age;
rl.question("What is your favorite color? \n", (color) => {
console.log(color);
rlcolor = color;
console.log("Hello " + rlname + ", you are " + rlage + " years old and your favorite color is " + rlcolor + ".");
rl.close();
})
})
})
}
getUserInput();
(Note that rl.close
can't be called until all the questions have been asked, so within the innermost callback.)
Using an async
function with promises would make this easier to follow, without the nested functions and deep indents.
Upvotes: 0
Reputation: 16069
The problem here is that readline.question
is asynchronous and you need to wait for each callback to return, before you (a) can use the input and (b) create the next question. You are executing the console.log statement, however, directly after the question
call. It's probably the easiest way to wrap the question
into a promise, so that you can await the response.
Here is an example using promises: https://stackoverflow.com/a/47999168/3233827
Upvotes: 0