-1

I tried to get my result printed on calculator display screen but when i checked the error it said "

calculator.js:14 Uncaught TypeError: Cannot read properties of undefined (reading 'getAttribute')
    at HTMLButtonElement.<anonymous>" 
Here is the code below:
var display = document.getElementById("calculator_display");
var point = document.getElementsByClassName("calc_button");
var operand1 = 0;
var operand2 = null;
var operator = null;

for (var i = 0; i < point.length; i++) {
    point[i].addEventListener("click", () => {

        var value = point[i].getAttribute("data-value");
        // var value= this.Array.getAttribute("data-value");




        if (value == "+") {
            operator = "+";
            operand1 = parseFloat(display.textContent)
        }
        else if (value == "=") {
            operand2 = parseFloat(display.textContent);

            var ans = eval(operand1 + " " + operator + " " + operand2);
            display.innerHTML = ans;

        }

        else {
            // console.log(display.innerHTML);
            display.innerHTML += display.innerHTML + value;

        }


    })

}

I tried to get the calculator number get displayed on pressing respective buttons.

Harrison
  • 1,654
  • 6
  • 11
  • 19
  • `.addEventListener("click", (event) => { const clickedElement = event.target; const value = clickedElement.getAttribute("data-value"); ...` to get the element firing the click event. You are passing a function to the addEventListener and its body is not aware of the array you are looping through. It's a different context – Diego D Dec 19 '22 at 15:19
  • The solution is to use `let` instead of `var` in your `for` loop, something I recommend to do simply in _all_ cases as there is no good reason to use `var` for _anything_ nowadays. The reason why `let` works in a special way in `for` is complicated but if you are interested, [here is the explanation](https://www.youtube.com/watch?v=Nzokr6Boeaw). – CherryDT Dec 19 '22 at 15:43
  • @CherryDT the question is closed and my comment expired at this point.. anyway just to make sense of my previous comment above, it seemed to me it was a matter of wrong logic. The event handler looks like needed the clicked element so that it was pointless to rely on the array anymore. Of course I agree with the `i` being the culprit I just made it short saying _the function body is not aware of the array looping..._ – Diego D Dec 19 '22 at 15:52
  • @DiegoD My comment was not a reply to yours, there was no `@DiegoD` in front ^^ I didn't mean to dispute what you were saying. – CherryDT Dec 19 '22 at 19:39
  • but mine had your name and it was a comment on your words that were confusing..but they will remain confused I see – Diego D Dec 20 '22 at 08:45

1 Answers1

-2

When using arrow functions in the event listener, you won't have access to the this variable. You can change it to a normal function to gain access to "this" which will be equivalent to point[i].

var display = document.getElementById("calculator_display");
var point = document.getElementsByClassName("calc_button");
var operand1 = 0;
var operand2 = null;
var operator = null;

for (var i = 0; i < point.length; i++) {

    // Changed to a regular function()
    point[i].addEventListener("click", function(){
      
        // Use "this" here
        var value = this.getAttribute("data-value");
        if (value == "+") {
            operator = "+";
            operand1 = parseFloat(display.textContent)
        } else if (value == "=") {
            operand2 = parseFloat(display.textContent);
            var ans = eval(operand1 + " " + operator + " " + operand2);
            display.innerHTML = ans;
        } else {
            // console.log(display.innerHTML);
            display.innerHTML += display.innerHTML + value;
        }
    })
}
<div id="calculator_display"></div>
<button class="calc_button" data-value="My Value">BUTTON</button>

Updated with regards to comment by @Quentin:

The problem is that by the time the element is clicked on, the value of i (which the function does have access to) has changed.

Jordan
  • 1,390
  • 2
  • 9
  • 24