Please read this very short article to get up to speed on what I am trying to do.
the main point is that, as the author says, I "need to ask the user several questions, ...validate the input data and re-ask questions when something was entered wrong." Furthermore, I might need to do more complex things to validate the input, aside from checking it against a regular expression. Like, for example, check to make sure the current input wasn't entered by the user at an earlier prompt.
I am interested in refactoring the main code snippet from this article so that it is promise-based. The obvious reason why I want to do this is to avoid callback hell in the event that i need to prompt the user more than two or three times. Do you have any suggestions on how to go about refactoring this? The thing that is tripping me up is the recursive call to ask()
, and also the fact that if a promise fails, thats it: its done. Whereas this code needs to loop over and over again until it gets valid input. SO I don't even really know where to start.
Also, if you have any "gordian knot"-type solutions, I am open to going in a completely different direction. Maybe Node has a built-in library for doing this kind of stuff that I am not aware of? Maybe readline
? I don't know though cuz I am too new to this stuff and the readline
API doesnt really make much sense to me...
Basically, if you can think of ANY way to refactor this so that I don't have to go deep into a callback nightmare, I would be grateful :)
Anyway, here is the code snippet in full:
function ask(question, format, callback) {
var stdin = process.stdin, stdout = process.stdout;
stdin.resume();
stdout.write(question + ": ");
stdin.once('data', function(data) {
data = data.toString().trim();
if (format.test(data)) {
callback(data);
} else {
stdout.write("It should match: "+ format +"\n");
ask(question, format, callback);
}
});
}
At first, promisify the stdin reader:
function askOnce(question){
var stdin = process.stdin, stdout = process.stdout;
stdin.resume();
stdout.write(question + ": ");
return new Promise(res => {
stdin.once('data', function(data) {
res(data.toString().trim());
});
});
}
So no asking is easy:
async function ask(question, format){
let answer;
do {
answer = await askOnce(question);
} while(!answer.test(format));
return answer;
}
Without async / await
its a bit uglier (using recursion and the promise flattening mechanism):
function ask(question, format){
return askOnce(question).then(answer => {
if(!answer.test(format))
return ask(question, format);
return answer;
});
}
are you reinventing the wheel? why not use the prompt module? this takes user input from the command prompt in a promise based manner.
https://www.npmjs.com/package/prompt
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With