Home > Software design >  AddEventListener runs only once and will only send 1 value into the array
AddEventListener runs only once and will only send 1 value into the array

Time:09-17

I am building a calculator as my 1st JS project (we've been strictly asked not to use eval).

I have set up an empty array, so that each time a button (with a number value) is clicked, the value will be put into the array using .push(). This is so that I can then concatenate all the number values together. Because if a user presses button 1 and then button 6, the number I will get is 16.

Problem is, the event listener will only run once and only add 1 number inside the string. The getValue function will first check if the variable is empty/undefined. If so, it will then push the number value of each button into the array...

let number1;
let number2;
let operator;

const getValues = () => {
  const numValue = document.querySelectorAll('.number');

  numValue.forEach(number => {
    number.addEventListener('click', () => {
      if (typeof number1 === 'undefined') {
        number1 = [];
        number1.push(number.value)
        display.innerHTML  = ` ${number.value}  `;
        console.log(number1);
      } else if (typeof number1 !== 'undefined' && typeof number2 === 'undefined') {
        number2 = number.value;
        display.innerHTML  = ` ${number.value}  `;
        console.log(number2)
      }
    })
  });

  const getOperators = () => {
    const operatorValue = document.querySelectorAll('.operator');

    operatorValue.forEach(operatorBtn => {
      operatorBtn.addEventListener('click', () => {
        if (typeof operator === 'undefined') {
          operator = operatorBtn.value;
          display.innerHTML  = `  <b>${operatorBtn.value}</b>  `;
          console.log(operator);
        }
      })
    })
  }

  getOperators();

  const calculation = () => {
    const equal = document.querySelector('.equal')

    equal.addEventListener('click', () => {
      if (typeof number1 !== 'undefined' && typeof number2 !== 'undefined' && operator.includes(' ')) {
        console.log( number1    number2)
        let result =  number1    number2;
        display.innerHTML  = ` = ${result} `;
        return result;
      } else if (typeof number1 !== 'undefined' && typeof number2 !== 'undefined' && operator.includes('-')) {
        console.log( number1 -  number2)
        let result =  number1 -  number2;
        display.innerHTML  = ` = ${result} `;
      } else if (typeof number1 !== 'undefined' && typeof number2 !== 'undefined' && operator.includes('x')) {
        console.log( number1 *  number2)
        let result =  number1 *  number2;
        display.innerHTML  = ` = ${result} `;
      } else if (typeof number1 !== 'undefined' && typeof number2 !== 'undefined' && operator.includes('/')) {
        let result =  number1 /  number2;
        display.innerHTML  = ` = ${result} `;
        console.log( number1 /  number2)
      }
    })
  }
  calculation()
}

getValues();
<main class="calculator">

  <div id="display"></div>

  <button class="button operator" value=" "> </button>
  <button class="button operator" value="-">-</button>
  <button class="button operator" value="x">x</button>
  <button class="button operator" value="/">/</button>

  <button class="button number" value="7">7</button>
  <button class="button number" value="8">8</button>
  <button class="button number" value="9">9</button>
  <button class="button number" value="4">4</button>
  <button class="button number" value="5">5</button>
  <button class="button number" value="6">6</button>
  <button class="button number" value="1">1</button>
  <button class="button number" value="2">2</button>
  <button class="button number" value="3">3</button>

  <button class="button number" value="0">0</button>
  <button class="button point" value=".">.</button>

  <input type="reset" class="button" id="reset">

  <button class="button equal" value="=">=</button>

</main>

CodePudding user response:

I have made some changes to make your code work. This still needs a lot of refactoring but it's a good start since you are beginning with this.

Things I have refactored have inline comments.

Other refactoring you can do is:

  1. Make the reset functionality work
  2. Make a high order function for the operations. Read more about it on mdn.
  3. Event delegation so that you do not attach event on every element but just on the parent. Read about this too on mdn.

let number1 = []; // Initialize the array
let number2 = []; // Initialize the array
// Keep a boolean value to know which number you are filling. You will push values into number array based on this value. It will be set to false once you press an operator.
let isFillingNumber1 = true; 
let operator;

const getValues = () => {
  const numValue = document.querySelectorAll('.number');

  numValue.forEach(number => {
    number.addEventListener('click', () => {
      if (isFillingNumber1) { // Note the modified if/else conditions
        number1.push(number.value)
        display.innerHTML  = ` ${number.value}  `;
        console.log(number1);
      } else {
        number2.push(number.value) // pushing value in number2 as well
        display.innerHTML  = ` ${number.value}  `;
        console.log(number2)
      }
    })
  });

  const getOperators = () => {
    const operatorValue = document.querySelectorAll('.operator');

    operatorValue.forEach(operatorBtn => {
      operatorBtn.addEventListener('click', () => {
        if (typeof operator === 'undefined') {
          operator = operatorBtn.value;
          display.innerHTML  = `  <b>${operatorBtn.value}</b>  `;
          isFillingNumber1 = false; // Making isFillingNumber1 false so as to enter in number2
          console.log(operator);
        }
      })
    })
  }

  getOperators();

  const calculation = () => {
    const equal = document.querySelector('.equal')

    equal.addEventListener('click', () => {
      number1 = number1.join(""); // Joining the array to make a string.
      number2 = number2.join("");
      if (typeof number1 !== 'undefined' && typeof number2 !== 'undefined' && operator.includes(' ')) {
        console.log( number1    number2)
        let result =  number1    number2;
        display.innerHTML  = ` = ${result} `;
        return result;
      } else if (typeof number1 !== 'undefined' && typeof number2 !== 'undefined' && operator.includes('-')) {
        console.log( number1 -  number2)
        let result =  number1 -  number2;
        display.innerHTML  = ` = ${result} `;
      } else if (typeof number1 !== 'undefined' && typeof number2 !== 'undefined' && operator.includes('x')) {
        console.log( number1 *  number2)
        let result =  number1 *  number2;
        display.innerHTML  = ` = ${result} `;
      } else if (typeof number1 !== 'undefined' && typeof number2 !== 'undefined' && operator.includes('/')) {
        let result =  number1 /  number2;
        display.innerHTML  = ` = ${result} `;
        console.log( number1 /  number2)
      }
    })
  }
  calculation()
}

getValues();
<main class="calculator">

  <div id="display"></div>

  <button class="button operator" value=" "> </button>
  <button class="button operator" value="-">-</button>
  <button class="button operator" value="x">x</button>
  <button class="button operator" value="/">/</button>

  <button class="button number" value="7">7</button>
  <button class="button number" value="8">8</button>
  <button class="button number" value="9">9</button>
  <button class="button number" value="4">4</button>
  <button class="button number" value="5">5</button>
  <button class="button number" value="6">6</button>
  <button class="button number" value="1">1</button>
  <button class="button number" value="2">2</button>
  <button class="button number" value="3">3</button>

  <button class="button number" value="0">0</button>
  <button class="button point" value=".">.</button>

  <input type="reset" class="button" id="reset">

  <button class="button equal" value="=">=</button>

</main>

  • Related