Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to take two consecutive input with the readline module of node.js?

I am creating a program to take input of two numbers from the command line and then showing there sum in node.js. I am using readline module to take stdin. Below is my code.

const readline = require('readline');

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

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

rl.question('Please enter the first number', (answer1) => {
    r2.question('Please enter the second number', (answer2) => {
        var result = (+answer1) + (+answer2);
        console.log(`The sum of above two numbers is ${result}`);
    });
    rl.close();
});

This program just show me "Please enter the first number" and when i enter a number like 5, it takes 5 for second input also and shows the answer 10

It don't ask second question at all. Please check this and tell me what is the problem. And if there is any better way to take multiple input please tell that.

I am a novice user in node.js

like image 514
Puneet Singh Avatar asked Apr 11 '16 06:04

Puneet Singh


4 Answers

Nested code/callback are terrible to read and maintain, here's a more elegant way to use Promise for asking multiple questions

node 8+

'use strict'

const readline = require('readline')

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

const question1 = () => {
  return new Promise((resolve, reject) => {
    rl.question('q1 What do you think of Node.js? ', (answer) => {
      console.log(`Thank you for your valuable feedback: ${answer}`)
      resolve()
    })
  })
}

const question2 = () => {
  return new Promise((resolve, reject) => {
    rl.question('q2 What do you think of Node.js? ', (answer) => {
      console.log(`Thank you for your valuable feedback: ${answer}`)
      resolve()
    })
  })
}

const main = async () => {
  await question1()
  await question2()
  rl.close()
}

main()
like image 115
jc1 Avatar answered Nov 15 '22 12:11

jc1


No need another variable, just use like this:

const readline = require('readline');

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

rl.question('Please enter the first number : ', (answer1) => {
    rl.question('Please enter the second number : ', (answer2) => {
        var result = (+answer1) + (+answer2);
        console.log(`The sum of above two numbers is ${result}`);
        rl.close();
    });
});
like image 41
Thamilhan Avatar answered Nov 15 '22 13:11

Thamilhan


I would ask the questions in an async function and wrap readline similarly to how Jason did it above. Although with slightly less code :)

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

function question(theQuestion) {
    return new Promise(resolve => rl.question(theQuestion, answ => resolve(answ)))
}

async function askQuestions(){
    var answer = await question("A great question")
    console.log(answer);
}
like image 23
user3032538 Avatar answered Nov 15 '22 13:11

user3032538


For those interested I put together this little module that takes an array of questions and returns a promise that resolves to an array of answers:

const readline = require('readline');

const AskQuestion = (rl, question) => {
    return new Promise(resolve => {
        rl.question(question, (answer) => {
            resolve(answer);
        });
    });
}

const Ask = function(questions) {
    return new Promise(async resolve => {
        let rl = readline.createInterface({
            input: process.stdin,
            output: process.stdout
        });

        let results = [];
        for(let i=0;i < questions.length;i++) {
            const result = await AskQuestion(rl, questions[i]);
            results.push(result);
        }
        rl.close();
        resolve(results);
    })
}

module.exports = {
    askQuestions: Ask 
}

Save that in a file called ask.js (or whatever you like) and use like this:

const { askQuestions } = require('./ask');

askQuestions([
   'What is question 1?',
   'What is question 2?',
   'What is question 3?'
])
    .then(answers => {
        // Do whatever you like with the array of answers
    });

Note: Will need a transpiler or recent version of Node as it uses a lot of ES6 features.

like image 28
Jason Avatar answered Nov 15 '22 12:11

Jason