Search code examples
javascriptnaninfinity

Why does my code return NAN and Infinity?


I'm trying to make a simple BMI calculator. However, if I just hit the calculate button, after the alert it renders the NAN as a 'result'. And if I just input the weight, it returns an Infinity response. I made several changes to the code structure but nothing solved this bug.

const heightInput = document.querySelector(".height-input");
const weightInput = document.querySelector(".weight-input");
const result = document.querySelector(".result");
const statement = document.querySelector(".statement");

document.querySelector(".calculate").addEventListener("click", calculateButton);


function calculateButton() {

  let height = heightInput.value;
  let weight = weightInput.value;
  let BMI = weight / (height ** 2);
  result.innerText = BMI.toFixed(1);

  if (BMI < 18.5) {
    statement.innerText = "Você está abaixo do peso ideal. Consulte um médico para fechar um melhor diagnóstico.";
  } else if ((BMI > 18.5) && (BMI < 24.9)) {
    statement.innerText = "Seu IMC está dentro da normalidade.";
  } else if ((BMI > 25) && (BMI < 29.9)) {
    statement.innerText = "Você está com sobrepeso. Consulte um médico para fechar um melhor diagnóstico.";
  } else if ((BMI > 30) && (BMI < 34.9)) {
    statement.innerText = "Você está com obesidade grau I. Consulte um médico para fechar um melhor diagnóstico.";
  } else if ((BMI > 35) && (BMI < 39.9)) {
    statement.innerText = "Você está com obesidade grau II. Consulte um médico para fechar um melhor diagnóstico.";
  } else if (BMI > 40) {
    statement.innerText = "Você está com obesidade grau III. Consulte um médico para fechar um melhor diagnóstico.";
  } else {
    window.alert("Por favor, adicione as informações abaixo");
  }
};

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>IMC</title>
  <script defer src="script.js"></script>
</head>

<body>
  <header>
    <h1>Calculadora de Índice de Massa Corporal (IMC)</h1>
  </header>
  <main class="calculator-container">
    <h1>Calcule o seu IMC</h1>
    <form action="#">
      <p>Insira sua altura em metros:</p>
      <label for="height">Altura:</label>
      <input class="height-input" id="height" name="height" type="number" placeholder="Ex: 1,70" required>
      <p>Insira o seu peso em kilogramas:</p>
      <label for="weight">Peso:</label>
      <input class="weight-input" id="weight" name="weight" type="number" placeholder="Ex: 70" required>
    </form>
    <button class="calculate">Calcular</button>
    <h3 class="result"></h3>
    <p class="statement"></p>
  </main>
</body>

</html>


Solution

  • You must check if both height and weight have a value.

    Because when you press calculate button with no input it can't be done the operation to get BMI, and the result is NaN (Not a number).

    Also, when you input a weight, but no height, the operation fall in a division by zero, and that's why the result is Infinity.

    So, the best way to avoid that kind of problems is to check if both height and weight have a value. If some of them is missing, just don't do nothing.

    function calculateButton() {
    
      let height = heightInput.value;
      let weight = weightInput.value;
    
      if (height == '' || weight == '') {
          return; //Nothing to do
      }
    
      let BMI = weight / (height ** 2);
      result.innerText = BMI.toFixed(1);
    
      if (BMI < 18.5) {
        //Here your code (I don't repeat it)
      }
    };
    

    But that's quite simple and you must go more ahead. You must check if values are valid numbers. You can use parseFloat() function, and then check with isNaN():

    function calculateButton() {
    
      let height = parseFloat(heightInput.value);
      let weight = parseFloat(weightInput.value);
    
      if (isNaN(height) || isNaN(weight)) {
          return; //Nothing to do
      }
    
      let BMI = weight / (height ** 2);
      result.innerText = BMI.toFixed(1);
    
      if (BMI < 18.5) {
        //Here your code (I don't repeat it)
      }
    };
    

    Finally, you can show an error message when a value is given but is not a number. I let you this on your own.