Home > Software design >  I am trying to create new operations for my calculator but only the sum function works, the other op
I am trying to create new operations for my calculator but only the sum function works, the other op

Time:11-10

I'm new to JavaScript and programming in general. I've taken a challenge of building a calculator usign HTML/CSS and JavaScript, I've already managed to add the sum function so the two numbers split by ' ' are summed and the result shows up in the same text input. But I can't seem to get it working for the other operations. For example, whenever I try to subtract, let's say 5-3, the result is -8...

Also, if I make a different operation first, the other operations I try to make after will display 'NaN' in the text input. For example, if I operate a sum first and then try to operate a subtraction, the result will not be "-8", it will display 'NaN' instead, and vice versa...

var equals = document.querySelector('#equals');
// The textfield element
var visor = document.getElementById("visor");
// The reset button
var resetBtn = document.getElementById("reset");
// Get all the buttons to an Array
var buttons = document.getElementsByClassName("key");
// Get all operators button
var plus = document.getElementById("plus");
var subtract = document.getElementById("subtract");
var multiply = document.getElementById("multiply");
var divide = document.getElementById("divide");

function numbersAndOperators() {

  Array.prototype.forEach.call(buttons, (button) => {
    button.addEventListener("click", () => {
      visor.value  = button.innerText
    })
  })

  // Add click event listener to reset button
  resetBtn.addEventListener("click", () => {
    visor.value = null
  })
}

plus.addEventListener('click', function() {
  equals.addEventListener('click', function() {
    var valAdd = visor.value.split(' ');
    visor.value = valAdd.reduce((a, c) => a   Number(c), 0);
  });
});

subtract.addEventListener('click', function() {
  equals.addEventListener('click', function() {
    var valSub = visor.value.split('-');
    visor.value = valSub.reduce((a, c) => a - Number(c), 0);
  });
});

multiply.addEventListener('click', function() {
  equals.addEventListener('click', function() {
    var valMul = visor.value.split('*');
    visor.value = valMul.reduce((a, c) => a * Number(c), 0);
  });
});

divide.addEventListener('click', function() {
  equals.addEventListener('click', function() {
    var valDiv = visor.value.split('/');
    visor.value = valDiv.reduce((a, c) => a / Number(c), 0);
  });
});

document.addEventListener("DOMContentLoaded", numbersAndOperators);
<body>
  <div >
    <div>
      <h1>Calc</h1>
    </div>
    <div >
      <p>Theme</p><input type="range" min="0" max="2" id="range"></div>
  </div>
  <div >
    <div><input type="text" id="visor"></div>
  </div>
  <div>
    <div >
      <button >7</button><button >8</button><button >9</button><button  id="del">DEL</button>
    </div>
    <div >
      <button >4</button><button >5</button><button >6</button><button  id="plus"> </button>
    </div>
    <div >
      <button >1</button><button >2</button><button >3</button><button  id="subtract">-</button>
    </div>
    <div >
      <button >.</button><button >0</button><button  id="divide">/</button><button  id="multiply">*</button>
    </div>
    <div >
      <button  id="reset">RESET</button><button  id="equals">=</button>
    </div>
  </div>
</body>

Previously, the JS for the equals button was like that:

equals.addEventListener('click', function(){
    if (visor.value.split(' ')){
        visor.value = visor.value.split(' ').reduce((a,c) => a   Number(c), 0);
    }
    if (visor.value.split('-')){
        visor.value = visor.value.split('-').reduce((a,c) => a - Number(c), 0);
    }
    if (visor.value.split('*')){
      visor.value = visor.value.split('*').reduce((a,c) => a * Number(c), 0);
    }
    if (visor.value.split('/')){
      visor.value = visor.value.split('/').reduce((a,c) => a / Number(c), 0);
    }
});

document.addEventListener("DOMContentLoaded", numbersAndOperators);

CodePudding user response:

The problem is with the way you're using reduce(). You're starting with an initial value 0, then using reduce() to subtract each number from it. So 5-3 is being treated as 0-5-3.

After splitting, you should use the first value as the initial value, then subtract the rest. So change

visor.value = valSub.reduce((a, c) => a - Number(c), 0);

to

visor.value = valSub.slice(1).reduce(a, c) => c - Number(c), Number(valSub[0]));

CodePudding user response:

Alright, I managed to solve the issue with a friend based on @Barmar's contribution. All I had to do was change the parameters from Number() to parseFloat(), but I had to do it on both parameters, something like that: parseFloat(a) - parseFloat(c).

´´´ equals.addEventListener('click', function(){ if (visor.value.split('-')){ visor.value = visor.value.split('-').slice(1).reduce((a, c) => parseFloat(a) - parseFloat(c), (visor.value.split('-')[0])); } if (visor.value.split(' ')){ visor.value = visor.value.split(' ').slice(1).reduce((a, c) => parseFloat(a) parseFloat(c), (visor.value.split(' ')[0])); } if (visor.value.split('')){ visor.value = visor.value.split('').slice(1).reduce((a, c) => parseFloat(a) * parseFloat(c), (visor.value.split('*')[0])); } if (visor.value.split('/')){ visor.value = visor.value.split('/').slice(1).reduce((a, c) => parseFloat(a) / parseFloat(c), (visor.value.split('/')[0])); } }) ´´´

  • Related