0

A JavaScript beginner here. I would like to write a basic function that takes a path to a local text file and returns its contents. I am aware that this question has been asked like 1000 times now, for example here. But every single answer is different from each other, I have tried a few, and they don't seem to work. After googling for a bit, I was able to come up with the following solution

function readTextFile(path) {
    var reader = new FileReader();
    reader.onload = function(event) {
        var contents = event.target.result;
        console.log("File contents: " + contents);
    };

    reader.onerror = function(event) {
        console.error("File could not be read! Code " + event.target.error.code);
    };

    var file = new File([path], { type: 'plain/text' });
    reader.readAsText(file);
    return contents
}

However, for some reason it outputs the path itself, not the contents. Please suggest how this code can be fixed, shortened, improved.

I also tried fetch but I get the infamous cross-origin request error, that I could not figure out how to solve easily.

EDIT:

Ok, I'll add a few more lines to make things more clear

index.html:

<input type="file" id="jsonAddressInput" value="enter address here">

script.js

function myFunction() {
    var addressField = document.getElementById("jsonAddressInput");

    var addressText = addressField.value;
    console.log(addressText);

    var textContentsOfFile = readTextFile(addressText)
    //console.log(textContentsOfFile)
}

function readTextFile(path) {
    var reader = new FileReader();
    reader.onload = function(event) {
        var contents = event.target.result;
        console.log("File contents: " + contents);
    };

    reader.onerror = function(event) {
        console.error("File could not be read! Code " + event.target.error.code);
    };

    var file = new File([""], path, { type: 'plain/text' });
    reader.readAsText(file);
    return contents
}

It was mentioned that I can use the results of the to get file contents. Please suggest how to fix

Aleksejs Fomins
  • 688
  • 1
  • 8
  • 20
  • Look here: https://developer.mozilla.org/en-US/docs/Web/API/File/File the `File` constructor takes the bits to create the object from, not the path.If the object you are passing to `readAsText` is the file you get from an `` it will work. – ZorgoZ Oct 24 '19 at 18:36
  • 1
    Where are you trying to read the text file from? A website or the user's local machine? JavaScript cannot access just any file on a user's machine which is why the File constructor is asking for bits and not a path. – daddygames Oct 24 '19 at 18:39
  • I'm trying to read a file from local directory (same directory as the script and the web page). – Aleksejs Fomins Oct 24 '19 at 18:41
  • Would you be so kind to link to a page explaining what bits is? – Aleksejs Fomins Oct 24 '19 at 18:43
  • @AleksejsFomins read the link from my comment – ZorgoZ Oct 24 '19 at 18:44
  • @ZorgoZ I did. I meant to explain it, not define it in terms of other things I don't understand :D – Aleksejs Fomins Oct 24 '19 at 18:47
  • Your array is one. This is why you get the path as content. The explanation is there: _This is the file content encoded as UTF-8_ – ZorgoZ Oct 24 '19 at 18:47
  • Ah, sorry, I missed that. So this is not the right way to go? The file contents in UTF8 is what I want to get as a result... – Aleksejs Fomins Oct 24 '19 at 18:51
  • You can not bypass the security barriers of the browser. You can open only what the user selects in the input field. – ZorgoZ Oct 24 '19 at 19:01

1 Answers1

1

Here's an example how to read a local file:

function readJson(blob) {
    var reader = new FileReader();
    reader.onload = function(event) {
        contents = event.target.result;
    };

    reader.onerror = function(event) {
        console.error("File could not be read! Code " + event.target.error.code);
    };

    var file = new File(blob, { type: 'plain/text' });
    reader.readAsText(file);
}

let contents

document.querySelector("input").addEventListener("change", (e) => {
  contents = readJson(e.target.files);
})

document.querySelector("button").addEventListener("click", (e) => {
  console.log(contents);
})
<input type="file">

<button>show contents</button>

If you want the contents of a remote file, use fetch

marzelin
  • 10,790
  • 2
  • 30
  • 49
  • Hey, it works! But I ultimately want to be able to return the contents of the file, or store them in a global variable, so I could process them later – Aleksejs Fomins Oct 24 '19 at 19:25
  • Ok, I have figured out I can assign something to `document.myVariable`. However, if I print the contents of that variable outside the reader.onload function it appears undefined, but when I do it the 2nd time it works correctly. I suppose that the file reading is done asynchronously. Can I ask my function to wait for the reading to be done before returning? – Aleksejs Fomins Oct 24 '19 at 19:33
  • Ok, whatever, I figured out that if I add an extra button to display the file contents, it manages to load the file before I click on it. I will accept the answer, but I really appreciate any additional advice on the two points above, as it helps me to learn – Aleksejs Fomins Oct 24 '19 at 19:42
  • 1
    @AleksejsFomins I've changed the code to log the file on button press. The reading is indeed done asynchronously. You can't really make a function wait because javascript is a non-blocking language but you can make the code look like it was blocking with `async/await`. – marzelin Oct 24 '19 at 19:49