0

I've found many JavaScript tutorials on reading plain text from local files and on displaying that text onto a webpage element, but I cannot seem to find how to SAVE the data into an array that I can access from other parts of my script.

If I try to assign the text from the file to a global variable INSIDE the FileReader.onload() method, I can't access it OUTSIDE the method. Any advice?

The code below is for a school timetable project that I'm doing with my students that uses local files of courses, students, and teachers. I have a file input element defined as:

<input type="file" id="courseFile" onchange="School.addCourses(event);">

Then my School constructor includes the following arrays and methods:

function School (name) {
    this.courses = [];
    this.students = [];
    this.teachers = [];

    this.addCourses = function (event) {
        var fileInput = event.target;
        var r = new FileReader();
        r.readAsText(fileInput.files[0]);
        r.onload = function (e) {
            var text = r.result;
            var array = text.split("\n");
            document.getElementById("courseList").innerHTML = text;
            this.courses = array;
        }
    }
}

The text is loaded into text and then split into array and will even display on the page in the courseList element, but it does not copy the data into this.courses.

Derek P
  • 3
  • 2
  • `this` inside the function is not the same as the `this` outside. You either have to use a global reference or use `bind` http://stackoverflow.com/questions/2236747/use-of-the-javascript-bind-method – theCaveat Jun 15 '16 at 18:20
  • Sorry for my lack of understanding. By global reference, do you mean the solution offered by MISJHA below -- to use the literal object name, as in `School.course`? And I don't understand how to use the `bind()` method in this situation. Could you give me a little more instruction? – Derek P Jun 16 '16 at 17:17
  • See http://codepen.io/anon/pen/LZZJzv – theCaveat Jun 16 '16 at 19:09
  • Thank you so much!! I still don't know if I really understand how the `bind()` method works, but you fixed my problem! Take the rest of the day off knowing you made someone else very happy! – Derek P Jun 17 '16 at 17:36
  • Derek, what bind does is set a new value for the `this` variable inside the function. In general, an event handler will have `this` set to the object that triggered the event. So in your case, when you set `this.courses` inside the handler you were in fact creating a new object associated with the `this` which was the `input` object. Using `bind()` , the `this` from the outer function is preserved. – theCaveat Jun 17 '16 at 19:43

1 Answers1

0

The problem here is the scope of this inside addCourses. to access the function School scope you need to change this.courses = array to School.course = array

Hope this helps!

MISJHA
  • 998
  • 4
  • 12
  • Thanks for the quick response! Your advice works inside the onload() method -- if I add `alert(School.courses)` then it display the courses. But if I add `alert(this.courses)` outside the onload() method then it displays `undefined`. – Derek P Jun 15 '16 at 18:37
  • please note that `this.courses` is a property of School, so anywhere you want to reference it inside `addCourses` you will have to use `School.courses` – MISJHA Jun 15 '16 at 18:45
  • What if I want to add other methods to the `School` class that can access the `courses` data? If I have to always refer to `School.courses`, doesn't that defeat the purpose of using objects? Perhaps the `bind` method suggested above might help? – Derek P Jun 15 '16 at 19:42