Want to insert text into a <span>, Error Cannot read properties of undefined (reading 'span')

I am a complete and utter beginner making a simple calculator. The HTML file has two text fields (a number is entered in each) and one drop down selector with four options (add, subtract, multiply, divide). A JavaScript file is supposed to, on the press of a button, take the numbers entered into the fields plus the type of mathematical operation from the drop-down menu, perform the operation, and insert the result into a span element in the HTML page. When I try to run it and click the button the browser console says Uncaught TypeError: Cannot read properties of undefined (reading 'span') at HTMLButtonElement.<anonymous> (VM82 hopelessJS.js:11:20).

Code:

'use strict';

const calcButton = document.querySelector('button');

calcButton.addEventListener('click', function(evt) {
  var operation = document.querySelector('select').options.selectedIndex;
  var num1 = document.querySelectorAll('input')[0].value;
  var num2 = document.querySelectorAll('input')[1].value;

  if (operation == 0)
    document.body.p.span.innerHTML = num1 + num2; //apparently sth in this syntax is wrong?
  else if (operation == 1)
    document.body.p.span.innerHTML = num1 - num2;
  else if (operation == 2)
    document.body.p.span.innerHTML = num1 * num2;
  else if (operation == 3)
    document.body.p.span.innerHTML = num1 / num2;

});
body {
  font-family: sans-serif;
}

input {
  margin: 10px;
}

button {
  border: 1px solid;
  width: 180px;
  padding: 8px;
  text-align: center;
  margin: 10px;
}

span {
  font-weight: bold;
}
<body>
  <h1>Hopeless Calculator</h1>
  <input type="text">
  <select>
    <option value="+">+</option>
    <option value="-">-</option>
    <option value="*">*</option>
    <option value="/">/</option>
  </select>
  <input type="text">
  <br>
  <button type="button">Calculate: </button>
  <br>
  <p>Result: <span></span></p> //where I want the result inserted
</body>

>Solution :

You can’t get the <span> element by using those nonexistent properties. First, think about it. If document.body had two <p>s, then which would be document.body.p?

Instead, the DOM API uses .querySelector() and .querySelectorAll() to get elements with CSS selectors (there’s also .getElementById(), .getElementsByClassName(), etc.). The CSS selector for the <span> child of the <p> in the body is body>p>span. Because you only want to get one element, you’d use .querySelector(). Like this:

'use strict';

const calcButton = document.querySelector('button');

calcButton.addEventListener('click', function(evt) {
  var operation = document.querySelector('select').options.selectedIndex;
  var num1 = document.querySelectorAll('input')[0].value;
  var num2 = document.querySelectorAll('input')[1].value;

  const out = document.querySelector('body>p>span');
  if (operation == 0)
    out.innerHTML = num1 + num2; //apparently sth in this syntax is wrong?
  else if (operation == 1)
    out.innerHTML = num1 - num2;
  else if (operation == 2)
    out.innerHTML = num1 * num2;
  else if (operation == 3)
    out.innerHTML = num1 / num2;
});
body {
  font-family: sans-serif;
}

input {
  margin: 10px;
}

button {
  border: 1px solid;
  width: 180px;
  padding: 8px;
  text-align: center;
  margin: 10px;
}

span {
  font-weight: bold;
}
<body>
  <h1>Hopeless Calculator</h1>
  <input type="text">
  <select>
    <option value="+">+</option>
    <option value="-">-</option>
    <option value="*">*</option>
    <option value="/">/</option>
  </select>
  <input type="text">
  <br>
  <button type="button">Calculate: </button>
  <br>
  <p>Result: <span></span></p> //where I want the result inserted
</body>

Leave a Reply