More Crabbing

I have another curmudgeonly complaint. I have spent all day trying to figure out how to load a text file in Javascript. Now, forty years ago, on the Atari computers, you could load the text in a file with these three lines of code in the primitive programming language known as BASIC:

OPEN #1, 4, 0, ‘D:TEST.TXT’
INPUT #1, FILETEXT
CLOSE #1

In this example, ‘#1’ refers to the device number (which you set with some switches on each device), ‘4’ means that we are opening this only for reading from the disk drive, I can’t recall what the ‘0’ did, and ‘D:TEST.TXT’ means that we are loading a file named ‘TEST.TXT’ from the disk drive.

The second line loads the contents of TEST.TXT into a variable called ‘FILETEXT’. The third line wraps up the process. 

That’s all there is to it. This is one of the most fundamental operations in programming, and I have loaded files using assembly language, BASIC, Pascal, C++, and Java. The code for doing this is quite similar in every language. 

Now, file handling can become complicated when you’re dealing with special kinds of files. But the text file is the simplest file and is always easy to load. But not in Javascript. I have spent hours plodding through material on the Internet explaining how to load a text file in Javascript. There must be a million ways to accomplish this, none of them simple. Here’s one of the simpler examples:

<!DOCTYPE html>
<html>
  <
head>
    <title>Read Text File Tutorial</title>
  </head>
  <body>
    <input type="file" name="inputFile" id="inputFile">
    <br>
    <pre id="output"></pre>
    <script type="text/javascript">
      document
.getElementById('inputFile').addEventListener('change', function() {
        var file = new FileReader();
        file
.onload = () => {
          document
.getElementById('output').textContent = file.result;
        }

        file
.readAsText(this.files[0]);
      });
    </
script>
  </body>
</html>

That doesn’t look so bad, does it? When you run the page, it opens up a file selection dialogue from which you select a file, which is then loaded and displayed on the screen. How very sweet! Indeed, it neatly handles the input file selector process without any fuss for the programmer. 

But I don’t want to load any file by selecting it; I want something even simpler. I want to be able to specify in advance the name of the file that I want to load, and have the program read that file for me. You would think that this would be even easier, and that the code for doing so would be even shorter. You would be wrong. Let’s walk through the process. 

Obviously, you want to remove the line of code that specifies the input (the line right after ‘<body>’). But if you do that, you create a big problem. This line of code:

      document.getElementById('inputFile').addEventListener('change', function() {

has now been orphaned. It needs to know about an Element named ‘inputFile’, and you deleted the line of code that creates that Element. So you have to remove that line of code and replace it with something else. What if we simply strip it out? We’d get this:

<!DOCTYPE html> 
<html>
  <
head> 
    <title>Read Text File Tutorial</title> 
  </head> 
  <body> 
    <br> 
    <pre id="output"></pre> 
    <script type="text/javascript"> 
      var file = new FileReader(); 
      file
.onload = () => { 
        document
.getElementById('output').textContent = file.result;
      }
 
      file
.readAsText(this.files[0]);
    </
script> 
  </body> 
</html>

This doesn’t work; it generates this error message:

TypeError: undefined is not an object (evaluating 'this.files[0]')

Which makes perfect sense; after all, what in the hell is “this”?