Javascript calculator, one small problem

Hello everyone, I am building my calculator and I have run into a small syntax error that is breaking everything. I have used codepen’s “analyse js” feature and it just tells me I have a "undefined ) "
My project https://codepen.io/Dylanbozarth/pen/vYYKVNX
Here is my code
Thank you in advance for your help.

$(document).ready(function() {
  //store input from user 
  var inputs=[""];
  //string to store current input
  var totalString;
  // validtion array without dot
  var operators1 = ["add", "subtract", "divide", "multiply"];
  // with the dot 
  var operators2=["."];
  var nums = [0,1,3,4,5,6,7,8,9];
  // includes checks a value to see if it's true 
  function getValue(input){
    if(operators2.includes(inputs[inputs.length-1]===true && input==="decimal")){
      console.log("too many 'decimals'");
    }
  else if(inputs.length===1 && operators1.includes(input)===false){
    inputs.push(input);
  }
  else if(operators1.includes(inputs[inputs.length-1])===false){
    inputs.push(input);
  }
  else if(nums.includes(Number(input))){
    inputs.push(input);
      }
    }

                  
  function update(){
    totalString = inputs.join("");
    $("#display").html(totalString);
  }
  function getTotal(){
    totalString = inputs.join("");
    $("#display").html(eval(totalString));
  }
  //eval = evaluate 
  $("a").on("click", function(){
    if(this.id==="clear"){
      inputs=[""];
      update();
    }
    else if(this.id==="equals"){
      getTotal();
    }
    else{
      if(inputs[inputs.length-1].indexOf("add","subtract","multiply","divide","decimal")===-1){
         getValue(this.id);
         }
      else{
        getValue(this.id);
      }
    }
  });
  //using this.id will select what was clicked by id
});
    $("#display").html(eval(totalString));

This is your problem.
If I click the buttons “6”, “+”, “3”, “=” then totalString is “sixplusthree”. The eval function then tries to find a variable named sixplusthree, which is undefined. That causes an error.

1 Like

So what should I do to fix this? I tried using numbers like “1-2-3” for the ids but then the FCC tests fail. They have to be words

Given the way you’re trying to do this, using eval and a string to evaluate, you’re going to need to build a string that looks like 6+3 rather than sixplusthree.

How to do this? Again, the way to make the least changes to your code would be to change nums and operators1 from Array to Object. For each object property, use the key name. For each object property’s value, use the actual value you want in your string.

An example might look like:

let colors = {
  'red': '#FF0000',
  'fuchsia': '#FF00FF',
  'yellow': '#FFFF00',
  'silver': '#C0C0C0',
  'gray': '#808080',
  'olive', '#808000',
  'purple', '#800080',
  'maroon', '#800000',
  'aqua', '#00FFFF',
}; // there are others, but I'm tired of typing colors...

// Later, you would check if the color is in the object by
if(colors.hasOwnProperty(textInputValue) ){
  // if that property name exists in the object, we can use that property.
  //  we access it with the brackets notation, as in the line below
  document.querySelector("body").style.backgroundColor = colors[textInputValue];
}

For your use, I suggest using nums and operators, much as you have, but consider making them objects with your preferred properties. Then you can use your button id as the property name, and the value as… the value!.

Of course, an easier way might be to use classes on your anchors. If, for example, the operators had an operator-btn class, and the digits had a digit-btn class, you could assign the operator functionality to the operator, and the digit functionality to the digit, without having to worry about sorting one from the other in each function.

Just a suggestion there… :wink:

1 Like

Thanks for your great explanation, unfortunately I am very dumb.
So I set the classes like this

<a class="digit btn btn-primary" id="0">0</a>

How do I make the function reference the class?

getValue(this.id);            Do i type this.class.digit? I am not familiar with this

Think about changing your event handling. Currently, all events are going through

$("a").on("click", ...)

…but how might your code be simplified if you did:

const digitHandler = function(eventObj){
. // code to handle digits...
}

$(".digit").on("click", digitHandler)