-2

I am building a JavaScript Calculator as an exercise of TheOdinProject. I am facing problems in chained equations as my calculator is giving wrong results. How can I calculate the result as the value when someone clicks on any operator and the operation takes place if any second number for the calculation is provided. After the first calculation, the calculation should be performed with the previous result until Clear button is pressed.

For example - 3+3+3 is showing up as 6 when I chain the equation.

This is what I tried:-

    switch (e.target.textContent){
      //What I tried to fix the result
      case '+':
        if(n1!== null && n2===null){
          n2 = display.textContent;
          result = operate(n1, operator, n2);
          displayVal = result;
          display.textContent = displayVal;
          n1 = result;
        }
        operator = 0;
        displayVal = '0';
        display.textContent = 0;
        break;
        // ... other operators

Chained equations are not working, else if we press '=' after each operation, everything is fine.

Code :-

let displayVal = '0';
const display = document.querySelector('#display');
const numberButtons = document.querySelectorAll('.number');
const symbols = document.querySelectorAll('.symbol')
const equal = document.querySelector('#equal');
let equalPressed;
let result;

function add(n1, n2) {
    const sum = n1 + n2;
    displayVal = sum;
  display.textContent = sum;
  return sum;
}

function subtract(n1, n2) {
    displayVal = n1 - n2;
  display.textContent = displayVal;
  return n1-n2;
}

function multiply(n1, n2) {
    const product = n1 * n2;
  displayVal = product;
  display.textContent = displayVal;
  return n1*n2;
}

function divide(n1, n2){
  displayVal = n1
  display.textContent = n1/n2;
  return n1/n2;
}


numberButtons.forEach(btn => {

  btn.addEventListener('click', function(e){
    if (displayVal === 0 || displayVal === '0'){
      equalPressed = false;
      displayVal = e.target.textContent;
      display.textContent = displayVal;
    }
    else if(equalPressed === true){
      equalPressed = false;
      displayVal = e.target.textContent;
      display.textContent = displayVal;
    }
    else if(equalPressed === false){
      displayVal+=e.target.textContent;
      display.textContent = displayVal;
    }
    else{
      return;
    }
  })
})


let n1 = 0;
let operator = -1;
let n2 = 0;

symbols.forEach(symbol => {
  operator = 0;
  symbol.addEventListener('click', function(e){
    n1 = Number.parseInt(displayVal);
    switch (e.target.textContent){
      case '+':
        if(n1!== null && n2===null){
          n2 = display.textContent;
          result = operate(n1, operator, n2);
          displayVal = result;
          display.textContent = displayVal;
          n1 = result;
        }
        operator = 0;
        displayVal = '0';
        display.textContent = 0;
        break;
      case '-':
        operator = 1;
        displayVal = '0';
        display.textContent = 0;
        break;
      case '×':
        operator = 2;
        displayVal = '0';
        display.textContent = 0;
        break;
      case '÷':
        operator = 3;
        displayVal = '0';
        display.textContent = 0;
        break;
      case 'C':
        displayVal = '0';
        display.textContent = '0';
        n1 = 0;
        n2 = 0;
        break;
    }
  })
})

equal.addEventListener('click', function(){
  if (equalPressed === true){
    return;
  }
  n2 = Number.parseInt(displayVal);
  equalPressed = true;
  operate(n1, operator, n2);
})

function operate(n1, operator, n2){
  if (operator===0){
    add(n1, n2);
  }
  else if (operator === 1){
    subtract(n1, n2);
  }
  else if (operator === 2){
    multiply(n1,n2);
  }
  else if (operator === 3){
    divide(n1, n2);
  }
  else{
    return;
  }
}
<section id="display">0</section>
<section class="buttons">
  <div class="row" id="r1">
    <button id="clear" class="symbol">C</button>
    <button id="inverse" class="symbol"><sup>+</sup>/-</button>
    <button id="percent" class="symbol">%</button>
    <button id="divide" class="symbol">&divide;</button>
  </div>
  <div class="row" id="r2">
    <button id="seven" class="number">7</button>
    <button id="eight" class="number">8</button>
    <button id="nine" class="number">9</button>
    <button id="multiply" class="symbol">&times;</button>
  </div>
  <div class="row" id="r3">
    <button id="four" class="number">4</button>
    <button id="five" class="number">5</button>
    <button id="six" class="number">6</button>
    <button id="minus" class="symbol">-</button>
  </div>
  <div class="row" id="r4">
    <button id="one" class="number">1</button>
    <button id="two" class="number">2</button>
    <button id="three" class="number">3</button>
    <button id="plus" class="symbol">+</button>
  </div>
  <div class="row" id="r5">
    <button id="zero" class="number">0</button>
    <button id="dot" class="symbol">.</button>
    <button id="equal">=</button>
  </div>
</section>

Apologies for any mistake in my question. Any help would be greatly appreciated!

  • 2
    Questions should be self contained. Although a link can be helpful for background information, all essential information should be inside the question. – trincot May 01 '23 at 14:31
  • @trincot Anything else I can improve in the question ? – imkrishnasarathi May 01 '23 at 14:38
  • [What is a debugger and how can it help me diagnose problems?](https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems) [How to debug small programs?](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) Create a [mcve] and isolate the problem. – jabaa May 01 '23 at 14:44
  • `n1` should contain the result of the last operation. It contains the last input. – jabaa May 01 '23 at 14:50
  • I would delegate (not an answer to your question but still) `document.querySelector(".buttons").addEventListener('click', function(e){ .... })` – mplungjan May 02 '23 at 05:17

1 Answers1

0

if you want to add chained operations to your calc then prepare your code for it, actually i see that operation methods works with two values so you can fix it using the operation result as first value in a new operation

if (!!lastResult && userPressAnyOperator) {
  n1 = result of last operation
  n2 = user input after press any operator
  operate(n1, operator, n2)
}