Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make a function that re-calls a prompt if the original response is invalid?

Tags:

javascript

I'm fairly new to coding and web development in general, but for a course I'm on I've been asked to create a "fortune teller" page that uses prompt() to gather inputs from the user and generate a multiline string using them all.

I've been trying to write code to validate the prompt responses, but I can't figure out a way to put it all into a function.

If I only had one prompt, then I wouldn't have an issue, but because there are five different prompts, I can't figure out how to re-call each specific prompt when their response is invalid

At first I contemplated just repeating if.. while.. else.. for each prompt like this:

let mothersFirstName = validateString(prompt("What is your mother's first name?"));
if(mothersFirstName !== null && mothersFirstName !== ''){
    while(mothersFirstName.match(/\d/) !== null){
        alert("Please refrain from including numbers in your mother's name.");
        mothersFirstName = prompt("What is your mother's first name?");
    }
}else{
    while(mothersFirstName === null || mothersFirstName === ''){
        alertError();
        mothersFirstName = prompt("What is your mother's first name?");
    }
}

// let childhoodStreet = prompt("What is the name of the street you grew up on?");
// let favouriteChildhoodColour = prompt("What was your favourite colour as a child?");
// let currentAge = prompt("What is your current age?");
// let chosenNumber = prompt("Pick a number between 1 and 10");

// console.log(`In ${chosenNumber} years, you are going to meet your best friend named ${mothersFirstName} ${childhoodStreet}.
// You will get married in ${Number(currentAge) + Number(chosenNumber)} years and have ${Number(currentAge) % Number(chosenNumber)} children.
// In ${Math.round(Number(currentAge) / Number(chosenNumber))} years, you are going to dye your hair ${favouriteChildhoodColour}.`
// )

But I want to include it in a function like this:

function validateString(string){
    if(string !== null && string !== ''){
        while(string.match(/\d+/) !== null){
            alert("please refrain from including numbers in your response to this prompt");
            string = prompt("please re-answer the prompt");
            return string;
        }
    }else{
        while(string === null || string === ''){
            alertError
            string = prompt("please re-answer the prompt");
        }
    }
}

however, I don't just want a generic "please re-answer the prompt", and would instead like it to recall the specific prompt

like image 728
Max Saunders Avatar asked Oct 23 '25 16:10

Max Saunders


2 Answers

You can use the following approach

promptAndValidate function takes promptText string, errorText string and isValid function which should return a boolean.

This way you can specify different validation functions without code duplication.

function promptAndValidate(promptText, errorText, isValid) {
  let response = ''
  while (true) {
    response = prompt(promptText);
    if (!response) continue;

    if (isValid(response)) return response;

    alert(errorText);
  }
}

So for example to ask user to input mother's name:


const mothersFirstName = promptAndValidate(
  "What is your mother's first name?",
  "Please refrain from including numbers in your mother's name.",
  // make sure there are no numbers in response
  (response) => response.match(/\d/) === null
);

This way you can specify different promptText, errorText and validation functions

like image 155
Inder Avatar answered Oct 26 '25 04:10

Inder


You can either use a strategy called "recursion" where a function calls itself in some conditions:

function promptUser(message) {
  const response = prompt(message);
  if(!response) 
    return promptUser(message); // re-call this function and return sub-responses
  return response;
}

const userResponse = promptUser("Please enter your mother's first name");
console.log(userResponse);

Or, you can use a simple do while loop:

function promptUser(message) {
  let response = "";
  do {
    response = prompt(message);
  } while(!response);
  return response;
}

const userResponse = promptUser("Please enter your mother's first name");
console.log(userResponse)

The first approach is less performant, given that it will add a function call to the call stack every time the user enters an invalid value.

like image 41
Schnitzler Avatar answered Oct 26 '25 06:10

Schnitzler