Node.js Console: Ask the User for Input until Valid

Updated: January 1, 2024 By: Guest Contributor Post a comment

Introduction

Working with user input in Node.js applications is essential for interactive console applications. This guide will explore methods to prompt users and validate their input repetitively until it meets certain conditions.

Basic User Prompting

First, we need to know how to get user input. We’ll use Node.js built-in ‘readline’ module for basic input prompting:

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

readline.question('Enter your name: ', name => {
  console.log(`Hello, ${name}!`);
  readline.close();
});

Adding a Validation Loop

Now, we will continuously ask for the user’s name until they enter a non-empty string:

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

function getInput(query, validate) {
  readline.question(query, input => {
    if (validate(input)) {
      console.log(`You entered: ${input}`);
      readline.close();
    } else {
      console.log('Invalid input, try again.');
      getInput(query, validate);
    }
  });
}

getInput('Enter your name: ', input => input.trim() !== '');

Error Handling in User Input

Robust applications should handle potential errors gracefully. This can include handling cancellation of input (like pressing CTRL+C).

process.on('SIGINT', () => {
  console.log('\nInput cancelled by user.');
  readline.close();
  process.exit();
});

Advanced Validation Strategies

For more complex validation, we may employ regex or even third-party libraries like ‘validator’ to check for formats like emails, dates, etc:

const validator = require('validator');

function validateEmail(input) {
  return validator.isEmail(input);
}

getInput('Enter your email: ', validateEmail);

Async/Await Approach

For modern JavaScript, we can capitalize on async/await for more readable asynchronous code:

const util = require('util');
const readline = require('readline');

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

const question = util.promisify(rl.question.bind(rl));

async function getValidInput(query, validate) {
  while (true) {
    const input = await question(query);
    if (validate(input)) {
      console.log(`Valid input received: ${input}`);
      break;
    }
    console.log('Invalid input, please try again.');
  }
  rl.close();
}

(async function askUser() {
  await getValidInput('Enter a valid email: ', validator.isEmail);
  // More code can go here if necessary.
})();

Conclusion

Node.js provides us with the tools to create interactive console applications that can accept, validate, and process user input. By building upon the ‘readline’ module and incorporating modern JavaScript features such as async/await, we can control the flow of user input effectively to ensure that only valid data is accepted. Practice with different types of input and validation will hone the skill of creating robust command-line tools.