1

I made a simple Javascript calculator but values of the numbers and the operators aren't being outputted, I thought I had linked all the files properly. There is an error in the console that says

app.js:41 Uncaught TypeError: Cannot read property 'replace' of undefined at reverseNumberFormat (app.js:41) at HTMLButtonElement. (app.js:69)

I think that the ternary operator I used is causing problems but I don't know why. Can anyone help? Thanks.

function getHistory() {
  //maipulate history
  return document.getElementById('previous-operand').innerText;
}
//alert(getHistory());

function printHistory(num) {
  document.getElementById('previous-operand').innerText = num;
}

function getOutput() {
  document.getElementById('display').innerText;
}


function printOutput(num) {
  if (num == "") {
    document.getElementById('display').innerText = num;
  } else {
    //		..convert to comma seperated value
    document.getElementById('display').innerText = getFormattedNumber(num);
  }
}


function getFormattedNumber(num) {
  if (num == "-") {
    //if input is minus sign return emptpy value
    return "";
  }
  var n = Number(num);
  var value = n.toLocaleString("en");
  return value;
}

//printOutput("98586627")

///replace comma to empty charachter output values
function reverseNumberFormat(num) {
  return Number(num.replace(/,/g, ''));
}

var operator = document.getElementsByClassName("operator");
for (var i = 0; i < operator.length; i++) {
  operator[i].addEventListener('click', function() {
    if (this.id == "clear") {
      printHistory("");
      printOutput("");
    } else if (this.id == "backspace") {
      var output = reverseNumberFormat(getOutput()).toString();
      if (output) { //if output has a value
        output = output.substr(0, output.length - 1);
        printOutput(output);
      }
    } else {
      var output = getOutput();
      var history = getHistory();
      if (output == "" && history != "") {
        if (isNaN(history[history.length - 1])) {
          history = history.substr(0, history.length - 1);
        }
      }
      if (output != "" || history != "") {
        output = output == "" ?
          output : reverseNumberFormat(output);

        history = history + output;
        if (this.id == "=") {
          var result = eval(history);
          printOutput(result);
          printHistory("");
        } else {
          history = history.this.id;
          printHistory(history);
          printOutput("");
        }
      }
    }

  });
}

var number = document.getElementsByClassName("number");
for (var i = 0; i < number.length; i++) {
  number[i].addEventListener('click', function() {
    //get output commas removed
    var output = reverseNumberFormat(getOutput());
    //		
    if (output != NaN) { //if output is a number
      output = output + this.id;
      printOutput(output);
    }


  });
}
<div id="calculator-grid" class="calculator-grid">
  <div class="output">
    <div id="previous-operand"></div>
    <div id="display"></div>
  </div>
  <button id="clear" class="operator">AC</button>
  <button id="del" class="operator">DEL</button>
  <button id="divide" class="operator">÷</button>
  <button id="one" class="number">1</button>
  <button id="two" class="number">2</button>
  <button id="three" class="number">3</button>
  <button id="multiply" class="operator">*</button>
  <button id="four" class="number">4</button>
  <button id="five" class="number">5</button>
  <button id="six" class="number">6</button>
  <button id="add" class="operator">+</button>
  <button id="seven" class="number">7</button>
  <button id="eight" class="number">8</button>
  <button id="nine" class="number">9</button>
  <button id="subtract" class="operator">-</button>
  <button id="decimal" class="operator">.</button>
  <button id="zero" class="number">0</button>
  <button id="equals" class="span-two operator">=</button>
</div>

2
  • 1
    The code you have supplied doesn't reproduce the problem; Try to narrow the code down to include only the code that is needed to output the error you got. Commented Jan 31, 2020 at 11:49
  • 3
    Don't use output!=NaN instead use !Number.isNaN(output) Commented Jan 31, 2020 at 11:50

1 Answer 1

2

You are missing the return statement in the getOutput function.


function getOutput() {
  return document.getElementById('display').innerText;
}

You still will have an issue with adding the numbers, since you're using English words for those and trying to add them to numeric values, which will result in NaN. The above code solves the problem from your post, though.

function getHistory() {
  //maipulate history
  return document.getElementById('previous-operand').innerText;
}
//alert(getHistory());

function printHistory(num) {
  document.getElementById('previous-operand').innerText = num;
}

function getOutput() {
  return document.getElementById('display').innerText;
}


function printOutput(num) {
  if (num == "") {
    document.getElementById('display').innerText = num;
  } else {
    //		..convert to comma seperated value
    document.getElementById('display').innerText = getFormattedNumber(num);
  }
}


function getFormattedNumber(num) {
  if (num == "-") {
    //if input is minus sign return emptpy value
    return "";
  }
  var n = Number(num);
  var value = n.toLocaleString("en");
  return value;
}

//printOutput("98586627")

///replace comma to empty charachter output values
function reverseNumberFormat(num) {
  return Number(num.replace(/,/g, ''));
}

var operator = document.getElementsByClassName("operator");
for (var i = 0; i < operator.length; i++) {
  operator[i].addEventListener('click', function() {
    if (this.id == "clear") {
      printHistory("");
      printOutput("");
    } else if (this.id == "backspace") {
      var output = reverseNumberFormat(getOutput()).toString();
      if (output) { //if output has a value
        output = output.substr(0, output.length - 1);
        printOutput(output);
      }
    } else {
      var output = getOutput();
      var history = getHistory();
      if (output == "" && history != "") {
        if (isNaN(history[history.length - 1])) {
          history = history.substr(0, history.length - 1);
        }
      }
      if (output != "" || history != "") {
        output = output == "" ?
          output : reverseNumberFormat(output);

        history = history + output;
        if (this.id == "=") {
          var result = eval(history);
          printOutput(result);
          printHistory("");
        } else {
          history = history.this.id;
          printHistory(history);
          printOutput("");
        }
      }
    }

  });
}

var number = document.getElementsByClassName("number");
for (var i = 0; i < number.length; i++) {
  number[i].addEventListener('click', function() {
    //get output commas removed
    var output = reverseNumberFormat(getOutput());
    //		
    if (output != NaN) { //if output is a number
      output = output + this.id;
      printOutput(output);
    }


  });
}
<div id="calculator-grid" class="calculator-grid">
  <div class="output">
    <div id="previous-operand"></div>
    <div id="display"></div>
  </div>
  <button id="clear" class="operator">AC</button>
  <button id="del" class="operator">DEL</button>
  <button id="divide" class="operator">÷</button>
  <button id="one" class="number">1</button>
  <button id="two" class="number">2</button>
  <button id="three" class="number">3</button>
  <button id="multiply" class="operator">*</button>
  <button id="four" class="number">4</button>
  <button id="five" class="number">5</button>
  <button id="six" class="number">6</button>
  <button id="add" class="operator">+</button>
  <button id="seven" class="number">7</button>
  <button id="eight" class="number">8</button>
  <button id="nine" class="number">9</button>
  <button id="subtract" class="operator">-</button>
  <button id="decimal" class="operator">.</button>
  <button id="zero" class="number">0</button>
  <button id="equals" class="span-two operator">=</button>
</div>

Sign up to request clarification or add additional context in comments.

5 Comments

thanks, should I change the id's to numbers instead?
You shouldn't rely on IDs for that, use the data-* attributes instead. data-number="4" for example. You can access that in JS with element.dataset.number
data-operator, and a different class, then you can handle them separately (maybe by using the switch statement)
Also mention not to use output != NaN instead use !Number.isNaN(output)
You've posted this as a comment before, there's no need to repeat what you've said given that the OP will get a notification for that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.