Home > Mobile >  I am trying to evaluate if the input is an empty string or not a number in JavaScript
I am trying to evaluate if the input is an empty string or not a number in JavaScript

Time:02-06

I am trying to evaluate when the user inputs nothing (an empty string) or anything besides a number (Not a number). After I console log the an input of empty string a NaN is returned. I am not sure why the else-if statement is never recognized if I test for both an empty string or NaN value. This also ultimately affects my average total score.

const equationTag = document.querySelector('div#equation');
const inputBtn = document.querySelector('input.submit-btn');
const incorrectTag = document.querySelector('p#incorrect');
const correctTag = document.querySelector('p#correct');
const counterTag = document.querySelector('div#counter');
const exitButton = document.querySelector('button.exit-btn');
const displayButton = document.querySelector('button.display-btn');
const resultModal = document.querySelector('section.stats-section');
const averageP = document.querySelector('p.avg');
const guessP = document.querySelector('p.total-guesses');

let points = 0;
let correctGuesses = 0;
let incorrectGuess = 0;
let totalGuesses = 0;

/*
    Takes a min and max value as parameters, and
    returns a randomized integer
*/
function getRandomValue(min, max) {
    let r = Math.floor(Math.random() * (max - min   1))   min;
    return r;
}

// Displays multiplcation equation on the user interface
function displayEquation() {
    equationTag.textContent = `${integerOne} x ${integerTwo}=`;
}

// Returns the product of the two integers
function getProduct() {
    return integerOne * integerTwo;
}
/* 
    Event listener grabs user input on click
    and clears user input afterwards
 */
inputBtn.addEventListener('click', () => {
    const inputTag = document.querySelector('#num');
    const answer = parseFloat(inputTag.value);
    evaluateAnswer(answer);
    inputTag.value = "";
    inputTag.focus();
})

/* 
    Event listener grabs user input on enter key 
    and clears user input afterwards
*/
document.addEventListener("keydown", (event) => {
    if (event.key === "Enter") {
        const inputTag = document.querySelector('#num');
        const answer = parseFloat(inputTag.value);
        evaluateAnswer(answer);
        inputTag.value = "";
        inputTag.focus();
    }
})

exitButton.addEventListener('click', () => {
    setDisplayNone(resultModal);
})

displayButton.addEventListener('click', () => {
    setDisplayBlock(resultModal);
})

/*
    Takes a integer user input as an argument
    and compares whether the answer is correct or not.
*/
function evaluateAnswer(input) {
    console.log('Input value on eval ', input); // double checking value
    if (input !== getProduct()) {
        subtractPoint();
        incorrectGuess  ;
    } else if (input === ' ' || isNaN()) { // I am not sure why it's never evaluated
        console.log('Input value is empty or not a number ', input);
    } else {
        addPoint();
        correctGuesses  ;
    }
    totalGuesses  ;
    restartGame();
    guessP.textContent = "Incorrect Guesses= "   incorrectGuess;
    let average = (correctGuesses / totalGuesses);
    let precisionAvg = roundToPrecision(average, 2);
    averageP.textContent = `${(precisionAvg * 100).toFixed(2)}%`;
    // console.log('Total guesses: ', totalGuesses);
    // console.log('Incorrect ', incorrectGuess);
    // console.log("Average: ", average)
}

/*
    Evaluates if the points are less 
    than zero then restart points to 0
    else minus a point.
*/
function subtractPoint() {
    if (points <= 0) {
        points = 0;
    } else {
        points -= 1;
    }
    setDisplayBlock(incorrectTag);
    setDisplayNone(correctTag);
    incorrectTag.textContent = ('Incorrect: '   integerOne   ' x '   integerTwo   ' = '   getProduct());
    setPoint();
}

// Sets new updated point
function setPoint() {
    counterTag.textContent = points;
}

// Adds a point and updates earned points
function addPoint() {
    points  = 1;
    correctTag.textContent = ('Correct!');
    setDisplayBlock(correctTag);
    setDisplayNone(incorrectTag);
    setPoint();
}

/*
    Resets game and gets two new random integers
    and calls the displayEquation function.
*/
function restartGame() {
    integerOne = getRandomValue(0, 12);
    integerTwo = getRandomValue(0, 12);
    displayEquation();
}

// sets css display block and opacity 1 on element
function setDisplayBlock(displayResult) {
    displayResult.style.display = 'block';
    displayResult.style.opacity = 1;
}

// sets css display none and opacity 0 on element
function setDisplayNone(displayResult) {
    displayResult.style.display = 'none';
    displayResult.style.opacity = 0;
}

/*
    Takes a value as a parameter, and integer as a parameter
    returns a rounded value with two decimal places at most
    https://stackoverflow.com/questions/11832914/how-to-round-to-at-most-2-decimal-places-if-necessary/11832950#11832950
*/
function roundToPrecision(value, decimals = 2) {
    const pow = Math.pow(10, decimals);
    return Math.round((value   Number.EPSILON) * pow) / pow;
}

// run game on load
let integerOne = getRandomValue(0, 12);
let integerTwo = getRandomValue(0, 12);
displayEquation(); 
<body>

    <header>
        <h1 id="title">Multiply Me</h1>
    </header>

    <main>
        <div id="equation"></div>
        <div id="counter">0</div>
        <input type="number" id="num" value="" title="input">

        <input type="submit" >
        <button type="submit"  value="Show Results">&#x2b;</button>

        <div id="response">
            <p id="correct"></p>
            <p id="incorrect"></p>
        </div>

        <section >
            <h3 >Overall Results:</h3>
            <button >x</button>

            <article >
                <p ></p>
                <p ></p>
            </article>

        </section>


    </main>

</body>

CodePudding user response:

Several issues apart from not using isNaN correctly

You cannot see if a value is a single space after parseFloating it.

I would suggest

const answer = inputTag.value; 
evaluateAnswer(answer);

where you have this. Note the order and that I test the positive outcome before the negative

function evaluateAnswer(input) { 
  input = input.trim(); 
  if (input === "" || isNaN(input)) {   
    console.log('Input value is empty or not a number ', input);
    return; /* Any need to continue? */
  } else if (input === getProduct()) {
    addPoint();
    correctGuesses  ;
  } else  {
    subtractPoint();
    incorrectGuess  ;
  }

CodePudding user response:

You must first check that the input value is not empty, so you must modify the order of the condition. And it is better to add a return to exit the function when no value is entered so that a new question is not generated.

function evaluateAnswer(input) {
    console.log('Input value on eval ', input); // double checking value
    if (input === '' || isNaN(input)) { // I am not sure why it's never evaluated
        console.log('Input value is empty or not a number ', input);
        return;
    } else if (input !== getProduct()) {
        subtractPoint();
        incorrectGuess  ;
    } else{
        addPoint();
        correctGuesses  ;
    }
    totalGuesses  ;
    restartGame();
    guessP.textContent = "Incorrect Guesses= "   incorrectGuess;
    let average = (correctGuesses / totalGuesses);
    let precisionAvg = roundToPrecision(average, 2);
    averageP.textContent = `${(precisionAvg * 100).toFixed(2)}%`;
}
  • Related