skip to Main Content

Currently building a simple calculator with vanilla JS.
All buttons and calculations work but i needed help with switching operators

When the user performs an operation it works just fine, but let’s say the user pressed 2 and the operator "+" instead of "-" like he wanted, so instead of clearing the screen he presses "-" right after (so "2" then "+" then "-"), the screen displays "NaN -" instead of just switching the operator.

How would I fix that?

let currentOperand = '';
let previousOperand = '';
let currentOperation = undefined;
let isEqualsPressed = false;


numberBtns.forEach(btn => {
    btn.addEventListener('click', () => {
        inputNumber(btn.innerHTML)
    })
}) 

operationBtns.forEach(btn => {
    btn.addEventListener('click', () => {
        isEqualsPressed = true;
        chooseOperation(btn.innerHTML)
    })
}) 

allClear.addEventListener('click', clear);
del.addEventListener('click', deleteLastNumber);
equals.addEventListener('click', evaluate);

function clear() {
    currentOperand = '';
    previousOperand = '';
    currentOperandScreen.textContent = '';
    previousOperandScreen.textContent = '';
    operator = undefined;
} 

function deleteLastNumber() {
    currentOperandScreen.innerHTML = currentOperandScreen.innerHTML.slice(0, -1)
} 

function inputNumber(number) {
    if(currentOperandScreen.innerHTML.includes(".") && number === ".") return;

    if(currentOperandScreen.innerHTML.length < 16)
    currentOperandScreen.innerHTML = (currentOperandScreen.innerHTML).toString() + number.toString();
} 

function chooseOperation (operator) {
    if (previousOperand !== '') {
        evaluate()
    }  
    previousOperand = currentOperandScreen.innerHTML;
    currentOperation = operator;
    currentOperandScreen.innerHTML = '';
    previousOperandScreen.innerHTML = `${previousOperand} ${operator}`;
}

function evaluate() {
    let result;
    previousOperand = parseFloat(previousOperand)
    currentOperand = parseFloat(currentOperandScreen.innerHTML);

    switch (currentOperation) {
        case "+":
            result = add(previousOperand, currentOperand);
            break;
        case "-":
            result = subtract(previousOperand, currentOperand);
            break;
        case "÷":
            if(currentOperand === 0) {
                result = "Error"
            } else
            {result = divide(previousOperand, currentOperand)};
            break;
        case "x":
            result = multiply(previousOperand, currentOperand);
            break;
        default:
            return;
    }

    if (isEqualsPressed == true) {
        previousOperandScreen.innerHTML = `${previousOperand} ${currentOperation} ${currentOperand} =`
        currentOperandScreen.innerHTML = result;
    }

    currentOperand = result;
    currentOperandScreen.innerHTML = result;
    currentOperation = undefined;
    previousOperand = '';
}

thanks in advance!

2

Answers


  1. You could have a condition in your chooseOperation function to check whether the currentOperandScreen has a value. If it doesn’t, then the user is likely changing the operator.

    function chooseOperation (operator) {
       if(previousOperand !== '' && currentOperandScreen.innerHTML !== ''){
            currentOperation = operator
            return
       }else if (previousOperand !== '') {
            evaluate()
        }  
        previousOperand = currentOperandScreen.innerHTML;
        currentOperation = operator;
        currentOperandScreen.innerHTML = '';
        previousOperandScreen.innerHTML = `${previousOperand} ${operator}`;
    }
    
    Login or Signup to reply.
  2. I think you can add a judgment mark "isOperation" between each click on operationBtns, similar to throttling

    let currentOperand = '';
    let previousOperand = '';
    let currentOperation = undefined;
    let isEqualsPressed = false;
    let isOperation = false
    
    numberBtns.forEach(btn => {
        btn.addEventListener('click', () => {
            inputNumber(btn.innerHTML)
            isOperation = true
        })
    }) 
    
    operationBtns.forEach(btn => {
        btn.addEventListener('click', () => {
            isEqualsPressed = true;
            if(isOperation){
                 chooseOperation(btn.innerHTML)
            }
            isOperation = false
        })
    }) 
    
    

    Or there are other methods, such as determining that the input character and the data type of the last character displayed on the page are both strings and do not do so

    I hope my answer can help you

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