Cannot read property 'addEventListener' of null

Story Format: Sugarcube


const chooseFile = document.getElementById("choose-file");
const imgPreview = document.getElementById("img-preview");
chooseFile.addEventListener("change", function () {
function getImgData() {
  const files = chooseFile.files[0];
  if (files) {
    const fileReader = new FileReader();
    fileReader.addEventListener("load", function () { = "block";
      imgPreview.innerHTML = '<img src="' + this.result + '" />';

I’m trying to make it so the player can upload an image to be displayed. However I keep coming across this:

It is unclear where exactly you are executing your JavaScript example:

  1. within the Story JavaScript area of your project.
  2. within the content of a Passage, using a <<script>> macro.
  3. within the body of a Navigation Event handler.
  4. or somewhere else entirely.

But either way the issue is likely the result of you trying to add the Event Listener to an element that doesn’t exist at the time you call the addEventListener() function.

So where/when exactly in your project are you creating the HTML elements whose ID are choose-file and img-preview ?

If you are creating those HTML elements within the Story JavaScript area then they both need to be appended to the web-page’s Document Object Model (DOM) before you can use the getElementById() function to obtain references to them.

If those HTML elements are being created within the contents of a Passage then they will be briefly added to a buffer Node until the entire of that Passage’s contents has been processed, after which that buffer Node will be injected into the DOM. In this case the execution of the JavaScript will need to be either:

  1. done within a Navigation Event handler for an event (like :passagerender) that is passed a reference to the buffer Node, and the document.getElementById() function calls changed to use the buffer Node as their source.
  2. delayed until after the buffer Node has been injected, and one simple way to cause such a delay is to use the <<done>> macro to call a <<script>> macro that contains the JavaScript.

So without further information from you clarifying where the JavaScript is being executed, and where the HTML elements in question are being created, it is difficult to give a more precise answer.