skip to Main Content

I’m currently working on a basic calculator project using JavaScript, and I’m encountering an issue with displaying the calculations on the calculator screen.

As a beginner in JavaScript, I’ve been trying to implement the functionality where clicking on the calculator buttons should display the corresponding calculations on the screen. However, despite my efforts, nothing seems to be appearing on the calculator screen.

I’ve checked my code and attempted to debug, but as a newcomer to JavaScript, I’m finding it challenging to identify the root cause of the problem.

I would greatly appreciate it if someone could take a look at my code and provide guidance on what might be going wrong. I’m open to any suggestions or corrections to my code.

Here’s a simplified version of my JavaScript code:

let num1 = null;
let num2 = null;
let operator = null;
let result = null;
const calcBtn = document.querySelectorAll('.btn');
const outputNum = document.getElementById('outputNum');

//display the number clicked
const displayValue = () => {
  if (num1 !== null && operator !== null) {
    outputNum.innerHTML = `<p id="outputNum">${num1} ${operator} ${num2 !== null}</p>`
  }
}





//dertermine how calculator will work
const calcul = (num1, num2, operator) => {
  let result;

  switch (num1, num2, operator) {
    case '+':
      result = num1 + num2
      break;
    case '-':
      result = num1 - num2
      break;
    case '*':
      result = num1 * num2
      break;
    case '/':
      result = num1 / num2
      break;
    case '%':
      result = num1 % num2
      break;
  }
  return result;
}

//detect which button is clicked and assign it to a variable
const calculBtn = (e) => {

  const btn = e.target.textContent;

  if (btn >= '0' && btn <= '9') {
    if (num1 === null) {
      num1 = parseInt(btn);
    } else if (operator === null) {
      num1 * 10 + parseInt(btn);
    }
    if (num2 === null) {
      num2 = parseInt(btn);
    } else if (result === null) {
      num2 * 10 + parseInt(btn);

      displayValue();

    } else if (operator === 'C') {
      num1 = null;
      num2 = null;
      operator = null;
      outputNum.innerHTML = '';

    } else if (btn === '=') {
      const result = calcul(num1, num2, operator);
      outputNum.innerHTML = result;

      num1 = result;
      num2 = null;
      operator = null;

    } else {
      operator = btn;
      displayValue();
    }
  }

}




calcBtn.forEach(btn => {
  btn.addEventListener('click', calculBtn)
});
<div class="calculator">
  <div class="display">
    <div class="output">
      <p id="outputNum"></p>
    </div>
  </div>

  <div class="first-row">
    <div class="btn clear">C</div>
    <div class="btn operator">%</div>
    <div class="btn operator">/</div>
    <div class="btn operator">x</div>
  </div>

  <div class="second-row">
    <div class="btn ">7</div>
    <div class="btn">8</div>
    <div class="btn">9</div>
    <div class="btn operator">-</div>
  </div>

  <div class="third-row">
    <div class="btn">4</div>
    <div class="btn">5</div>
    <div class="btn">6</div>
    <div class="btn operator">+</div>
  </div>

  <div class="fourth-row">
    <div class="btn">1</div>
    <div class="btn">2</div>
    <div class="btn">3</div>
    <div class="btn result">=</div>
  </div>

  <div class="fifth-row">
    <div class="btn">0</div>
  </div>
</div>

2

Answers


  1. In calculBtn(), it seems more intuitive to try to see if the textContent is an integer, instead of using greater/less than or equal to operators with strings. So consider instead of:

    const btn = e.target.textContent;
    
    if (btn >= '0' && btn <= '9') {
    

    Do:

    const btn = e.target.textContent;
    const maybeInt = parseInt(btn, 10);
    if (Number.isInteger(maybeInt)) {
    

    Furthermore, again in calculBtn(), it seems life the conditional branches are flawed:

    // This if limits this code branch to 0-9 only, meaning:
    if (Number.isInteger(maybeInt)) {
      if (num1 === null) {
        …
      } else if (operator === null) {
        …
      }
      if (num2 === null) {
        …
      } else if (result === null) {
        // This branch is never visited since the parent conditional `if` branch
        // has already limited this code branch to 0-9 only.
      } else if (operator === 'C') {
        // This is never visited.
      } else if (btn === '=') {
        // This is never visited.
      } else {
        // This is never visited.
      }
    }
    

    This means the code never visits the later conditional branches as indicated above which means the non-number buttons never do anything, meaning operator is never assigned a value. This in turn means that in displayValue():

    if (num1 !== null && operator !== null) {
    

    This conditional would never evaluate to a truthy value and thus nothing would ever be displayed in the HTML.

    Instead, we should have the operator conditionals in calculBtn() be branches from the initial if, not inside it:

    if (Number.isInteger(maybeInt)) {
      …
    } else if (operator === 'C') {
      …
    } else if (btn === '=') {
      …
    } else {
      …
    }
    

    With all these changes, there will at least be a display once num1 and operator are not null:

    let num1 = null;
    let num2 = null;
    let operator = null;
    let result = null;
    const calcBtn = document.querySelectorAll(".btn");
    const outputNum = document.getElementById("outputNum");
    
    //display the number clicked
    const displayValue = () => {
      if (num1 !== null && operator !== null) {
        outputNum.innerHTML = `<p id="outputNum">${num1} ${operator} ${num2 !== null}</p>`;
      }
    };
    
    //dertermine how calculator will work
    const calcul = (num1, num2, operator) => {
      let result;
    
      switch ((num1, num2, operator)) {
        case "+":
          result = num1 + num2;
          break;
        case "-":
          result = num1 - num2;
          break;
        case "*":
          result = num1 * num2;
          break;
        case "/":
          result = num1 / num2;
          break;
        case "%":
          result = num1 % num2;
          break;
      }
      return result;
    };
    
    //detect which button is clicked and assign it to a variable
    const calculBtn = (e) => {
      const btn = e.target.textContent;
      const maybeInt = parseInt(btn, 10);
      if (Number.isInteger(maybeInt)) {
        if (num1 === null) {
          num1 = parseInt(btn);
        } else if (operator === null) {
          num1 * 10 + parseInt(btn);
        }
        if (num2 === null) {
          num2 = parseInt(btn);
        } else if (result === null) {
          num2 * 10 + parseInt(btn);
          displayValue();
        }
      } else if (operator === "C") {
        num1 = null;
        num2 = null;
        operator = null;
        outputNum.innerHTML = "";
      } else if (btn === "=") {
        const result = calcul(num1, num2, operator);
        outputNum.innerHTML = result;
    
        num1 = result;
        num2 = null;
        operator = null;
      } else {
        operator = btn;
        displayValue();
      }
    };
    
    calcBtn.forEach((btn) => {
      btn.addEventListener("click", calculBtn);
    });
    <div class="calculator">
      <div class="display">
        <div class="output">
          <p id="outputNum"></p>
        </div>
      </div>
    
      <div class="first-row">
        <div class="btn clear">C</div>
        <div class="btn operator">%</div>
        <div class="btn operator">/</div>
        <div class="btn operator">x</div>
      </div>
    
      <div class="second-row">
        <div class="btn">7</div>
        <div class="btn">8</div>
        <div class="btn">9</div>
        <div class="btn operator">-</div>
      </div>
    
      <div class="third-row">
        <div class="btn">4</div>
        <div class="btn">5</div>
        <div class="btn">6</div>
        <div class="btn operator">+</div>
      </div>
    
      <div class="fourth-row">
        <div class="btn">1</div>
        <div class="btn">2</div>
        <div class="btn">3</div>
        <div class="btn result">=</div>
      </div>
    
      <div class="fifth-row">
        <div class="btn">0</div>
      </div>
    </div>
    Login or Signup to reply.
  2. There are some issues in your code:

    1. In the calculBtn function, you mixed up the if bracket endings – there is one big if (btn >= '0' && btn <= '9'), and in it (operator === 'C'), (btn === '='), and so on, but it should look more like in the code below.

    2. In the calculBtn function, there should be a num1 = before num1 * 10 + parseInt(btn) (Without assignment, it is just a useless statement), and the same later with num2.

    3. else if (operator === 'C') -> else if (btn === 'C')

    const calculBtn = (e) => {
    
        const btn = e.target.textContent;
    
        if (btn >= '0' && btn <= '9') {
            if (num1 === null) {
                num1 = parseInt(btn);
            } else if (operator === null) {
                num1 = num1 * 10 + parseInt(btn);
            }
            if (num2 === null) {
                num2 = parseInt(btn);
            } else if (result === null) {
                num2 = num2 * 10 + parseInt(btn);
    
                displayValue();
    
            }
        } else if (btn === 'C') {
            num1 = null;
            num2 = null;
            operator = null;
            outputNum.innerHTML = '';
    
        } else if (btn === '=') {
            const result = calcul(num1, num2, operator);
            outputNum.innerHTML = result;
    
            num1 = result;
            num2 = null;
            operator = null;
    
        } else {
            operator = btn;
            displayValue();
        }
    }
    

    After fixing those problems, the text on the top should be displaying.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search