3

I just want to mention that I tried a bunch of techniques from blogs for getting user input but the examples were always in the context of a program that only asks for user input... and they always work but there's never any problem of node.js continuing on to the next lines of code because there are none.

I have to get user input and then verify that the input is valid so I created this construct:

while ( designAppealTest(subject) == false ) {
            subject[DESIGN_APPEAL] = ei.errorInput('designAppeal for the subject', iteration, subject[DESIGN_APPEAL])
        }

The function that it calls is this:

module.exports.errorInput =  function (fieldName, iteration, originalValue) {
    originalValue = originalValue || 'false'
    console.log('\n\n' + fieldName + ' for the subject' + ' contains an invalid value in for #' + i)

    if (originalValue !== false)
        console.log('original value of field = ' + originalValue)

    console.log('\nPlease enter a new value for it:\n')

    process.stdin.on('data', function (text) {
        console.log('received data:', text);
        return text;
    });

}

This works except that it keeps going through the while loop before the user has a chance to input a value. So all I see is the prompt asking the user to input a value 40,000 times a second. How can I make node.js wait until a value is entered before continuing the loop? Is the construct itself wrong or is it because I'm not halting it from being asynchronous?

CFrei:

Okay I added a callback to check() itself as well:

checkedSubject = check(subject, function(v) {
            return v;
        });

        console.log('checkedSubject = ' + checkedSubject)

        function check(listing, callback) {
            if (designAppealTest(subject) == false ) {
                ei.errorInput('designAppeal', iteration, listing[DESIGN_APPEAL], function(v) {
                    listing[DESIGN_APPEAL] = v;
                    check(listing)
                    });
            } else {
                callback(listing);
            }
        }

I'm still getting the same problem - it will ask for input but execute everything after it immediately.

2
  • To make things easier, you might look into using a pre-existing module from npm for handling user input from the terminal. Examples include inquirer and prompt. Commented Sep 13, 2014 at 17:26
  • I just tried the "prompt" module but I run into the same problem.. it's not waiting for user input... it'll ask for it but immediately execute whatever line is next so there's no time to input anything. Commented Sep 13, 2014 at 19:15

3 Answers 3

5

Since this question is a bit old, but I guess it still get's a lot of traffic from google: You should take a look at nodejs readline

const readline = require('readline');

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

rl.question('What do you think of Node.js? ', (answer) => {
  // TODO: Log the answer in a database
  console.log(`Thank you for your valuable feedback: ${answer}`);

  rl.close();
});
Sign up to request clarification or add additional context in comments.

Comments

0

Well, the async approach is about "never coming back" to any return value, just give the next callback to the function. Your "loop" should look like that:

function check() {
    if (designAppealTest(subject) == false ) {
            ei.errorInput('designAppeal for the subject', iteration, subject[DESIGN_APPEAL], function(v) { subject[DESIGN_APPEAL] = v; check() })
    }
}

(Please note the recursive call to simulate your "while".)

And instead of

return text;

you call that function (lets name it cb):

cb(text)

And yes, libs like async or Promise-Library help to make that look all a bit nicer.

7 Comments

I edited my post trying out your suggestions.. maybe you can check it out and let me know if I missed the point or not?
You're getting closer. ;) So add another callback to the check-function and call that in the "else"-tree. Really all your functions should look like function(value, ..., cb) and you get in the habit of calling these cb at "the end" of your function, just like you do "return" now.
Updated the OP again... I think I implemented what you said properly.. however I'm getting the same issue.
You can't use return.
ah so I'd literally have to put the rest of the program inside the callback, is that the idea? I was trying to avoid this to make it more maintainable since it's a sizeable program. I guess I was hoping for like a... "halt_process" method I can wrap the code in that I want to execute synchronously.
|
0

That's just how node.js works, it is designed around asynchronous, non-blocking I/O for high concurrency. If you need help organizing control flow because of how node.js works, you might look into using a module such as async.

1 Comment

So what would be an asynchronous way to accomplish waiting for a user's input? Maybe I'm totally approaching this wrong for node.js's capabilities? I'm relatively new to programming so any help with this would be appreciated.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.