Duuliye
Duuliye

Reputation: 1

Why does initialising the variable outside the event handler and then reassigning it only allow the code to work once?

I'm making a BMI calculator and it works only one time. Which I don't understand. I initialised 2 let variables outside the click event handler just to get the input elements. When I wanted to convert the variables' values using the 'Number()' it worked one time.

I played with the code until it worked everytime I clicked the button. But I don't understand why it worked now. So, I moved the declaration and initialisation of the variable to get the input elements inside the click event handler.

I don't understand the logic. It's the same code. Only real difference is the input element variables where declared and initialised in and outside of the click event handler. The variables in question are "weight" and "height".

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="script.js" defer></script>
</head>
<body>
  <div style="display: inline-block; vertical-align: top;">
    <div>
      <div>Weight:</div>
      <div><input type="text" id="weight" style="text-align: end;"></div>
    </div>
    <div>
      <div>Height:</div>
      <div><input type="text" id="height" style="text-align: end;"></div>
    </div>
    <button id="btn" style="margin-top: 10px;">Calculate</button>
    <p id="result"></p>
  </div>
  <div style="display: inline-block; vertical-align: top; background-color: aquamarine; border-radius: 7px;">
    <p>BMI Range</p>
    <div>
      <div style="display: inline;">Less than 18.5:</div>
      <p id="underweight" style="display: inline;">Underweight</p>
    </div>
    <div>
      <div style="display: inline;">18.5-24.9:</div>
      <p id="healthy" style="display: inline;">Healthy</p>
    </div>
    <div>
      <div style="display: inline;">25-29.9:</div>
      <p id="overweight" style="display: inline;">Overweight</p>
    </div>
    <div>
      <div style="display: inline;">Over 30:</div>
      <p id="obese" style="display: inline;">Obese</p>
    </div>
  </div>
</body>
</html>

The js below worked ONLY ONCE!!

const btn = document.getElementById("btn")
const result = document.getElementById("result")

let underWeight = document.getElementById("underweight")
let healthy = document.getElementById("healthy")
let overWeight = document.getElementById("overweight")
let obese = document.getElementById("obese")

let weight = document.getElementById("weight")
let height = document.getElementById("height")

btn.addEventListener('click', () => {
  weight = Number(weight.value);
  height = Number(height.value);
  if(isNaN(weight) || isNaN(height) || height === 0 || weight === 0){
    result.innerHTML = "Please type a number"
  } else{
    const bmi = Math.floor(weight/Math.pow(height, 2))
    if(bmi < 18.5){
      result.innerHTML = "You are Underweight. Your BMI is  " + bmi;
    } else if(bmi >= 18.4 && bmi <= 24.9){
      result.innerHTML = "You are Healthy. Your BMI is " + bmi;
    } else if(bmi >= 25 && bmi <= 29.9){
      result.innerHTML = "You are Overweight. Your BMI is " + bmi;
    } else{
      result.innerHTML = "You are Obese. Your BMI is " + bmi;
    }
  }
})

The js below did work!!

const btn = document.getElementById("btn")
const result = document.getElementById("result")

let underWeight = document.getElementById("underweight")
let healthy = document.getElementById("healthy")
let overWeight = document.getElementById("overweight")
let obese = document.getElementById("obese")

btn.addEventListener('click', () => {
  let weight = Number(document.getElementById("weight").value);
  let height = Number(document.getElementById("height").value);
  if(isNaN(weight) || isNaN(height) || height === 0 || weight === 0){
    result.innerHTML = "Please type a number"
  } else{
    const bmi = Math.floor(weight/Math.pow(height, 2))
    if(bmi < 18.5){
      result.innerHTML = "You are Underweight. Your BMI is  " + bmi;
    } else if(bmi >= 18.4 && bmi <= 24.9){
      result.innerHTML = "You are Healthy. Your BMI is " + bmi;
    } else if(bmi >= 25 && bmi <= 29.9){
      result.innerHTML = "You are Overweight. Your BMI is " + bmi;
    } else{
      result.innerHTML = "You are Obese. Your BMI is " + bmi;
    }
  }
})

Upvotes: 0

Views: 37

Answers (1)

Barmar
Barmar

Reputation: 782181

When you do

weight = Number(weight.value);

you're reassigning the global variable weight. The next time the event listener runs, weight no longer refers to the input element, it contains the number that was typed the previous time. So weight.value doesn't return what was typed into the input this time. It returns undefined because numbers don't have a value property, and Number(undefined) returns NaN.

Try to avoid reusing variable names. Change this to something like

let weight_value = Number(weight.value);

(and similar for height) and your code will work.

Upvotes: 2

Related Questions