0

I wanted to make yet again another calculator, this time a bit more "stylish". I was designing it and then wanted to test it. I ran into a problem though: It showed me error: `

Uncaught TypeError: Cannot read properties of null (reading 'value')

` I know what is causing the problem, but I cannot find a solution.

Here is my code:

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Calculator</title>
    <link rel="stylesheet" href="style.css">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.0.2/css/bootstrap.min.css">
</head>
<script src="index.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/js/all.min.js" integrity="sha256-qM7QTJSlvtPSxVRjVWNM2OfTAz/3k5ovHOKmKXuYMO4=" crossorigin="anonymous"></script>
<script src=https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.3.0/math.min.js></script>
<body>
    <div class="d-flex flex-column justify-content-center w-100 h-100">
        <div class="container-white">
            <div class="d-flex flex-column justify-content-center align-items-center">
                <h1>Calculator</h1>
                <div class="calc-main">
                    <input type="text" id='display'>
                    <div class="calc-basic input-group">
                        <input type="button" value="1" class="btn numbers" onclick="insert('1');">
                        <input type="button" value="2" class="btn numbers" onclick="insert('2');">
                        <input type="button" value="3" class="btn numbers" onclick="insert('3');">
                        <input type="button" value="+" class="btn operators" onclick="insert('+');">
                        <input type="button" value="=" class="btn functions" onclick="equals();">
                    </div>
                    <br>
                    <div class="calc-basic btn-group">
                        <button class="btn numbers" onclick="insert('4');">4</button>
                        <button class="btn numbers" onclick="insert('5');">5</button>
                        <button class="btn numbers" onclick="insert('6');">6</button>
                        <button class="btn operators" onclick="insert('-');">-</button>
                        <button class="btn operators" onclick="divide()">/</button>
                    </div>
                    <br>
                    <div class="calc-basic btn-group">
                        <button class="btn numbers" onclick="insert('7');">7</button>
                        <button class="btn numbers" onclick="insert('8');">8</button>
                        <button class="btn numbers" onclick="insert('9');">9</button>
                        <button class="btn operators" onclick="multiply();">*</button>
                        <button class="btn numbers" onclick="insert('.');">.</button>
                    </div>
                    <br>
                </div>
            </div>
        </div>
    </div>
</body>
</html>

JavaScript

`

let display = document.getElementById('display');
let buttons = document.getElementsByClassName("button");

function insert(sym) {
  display.value += sym;
}


function equals() {
    if ((display.value).indexOf("^") > -1 ) {
        let base = (display.value).slice(0, (display.value).indexOf("^"));
        let exponent = (display.value).slice((display.value).indexOf("^") + 1 );
        display.value = eval("Math.pow(" + base + "," + exponent + ")");
    } else {
        display.value = eval(display.value)
    }
}


function multiply() {
    display.value += "*";
}

function divide() {
    display.value += "/";
}

As I said, I know what's causing the issue: for some reason, it cannot find display.value, it finds it as null, however if I replace every 'display' of the code to:

document.getElementById('display')

it works perfectly fine. I don't know if I have made a typo that went unnoticed or another mistake but it just doesn't work.

Thanks in Advance.

PS: You will notice that some elements are input elements instead of button elements, I was trying to figure out a solution, but still couldn't :).

  • If `display` is initialized before the DOM is loaded, then there is nothing for it to retrieve and thus undefined. – mykaf Nov 21 '22 at 19:19
  • Inline event handlers like `onclick` are [bad practice](/q/11737873/4642212). They’re an [obsolete, cumbersome, and unintuitive](/a/43459991/4642212) way to listen for events. Always [use `addEventListener`](//developer.mozilla.org/en/docs/Learn/JavaScript/Building_blocks/Events#inline_event_handlers_%E2%80%94_dont_use_these) instead. If you fix that, then the easy and modern fix for `display` being `null` is to use ``. _“it cannot find `display.value`, it finds it as `null`”_ — That’s inaccurate. `display` is `null`, not `display.value`. – Sebastian Simon Nov 21 '22 at 19:24
  • Use [event delegation](//developer.mozilla.org/en/docs/Learn/JavaScript/Building_blocks/Events#Event_delegation) instead of adding several event listeners — it’s more maintainable and applies to dynamically added elements. See [the tag info](/tags/event-delegation/info) and [this Q&A](/a/55452921/4642212). – Sebastian Simon Nov 21 '22 at 19:26
  • I forgot to say, I used addEventListener (alone and with an array) and the same happened, so I switched to `onclick` and later to `onmousedown`. I made it work by adding the defer attribute in my script. Thanks for all the suggestions! – Thanasis Lanaras Nov 21 '22 at 21:23

0 Answers0