4

I am writing a TypeScript browser application. I need to read the contents of an XML file, and store it in a class. I am having issues with the 'this' object. Here is what I have so far:

class FileTools {
  text: string;

  readSingleFile(e) {
    var fileName = e.target.files[0];
    if (!fileName) {
        return;
    }
    var reader = new FileReader();
    reader.onload = file => {
        var contents: any = file.target;
        this.text = contents.result; <== Issue here. 'this' is the filereader
    };
    reader.readAsText(fileName);
}

  start() {
    document.getElementById("file-input").addEventListener("change", this.readSingleFile, false);
  }
}

window.onload = () => {
  var tcx = new FileTools();
  tcx.start();
};

The HTML has a file selection box input type="file" id="file-input"

The issue is that when the file is loaded, using the 'this' points to the file reader, not to my class. If I add a 'self' variable first like this:

  readSingleFile(e) {
    var fileName = e.target.files[0];
    if (!fileName) {
        return;
    }
    var reader = new FileReader();
    var self = this;
    reader.onload = file => {
        var contents: any = file.target;
        self.text = contents.result; <== Issue here. 'this' is the filereader
    };
    reader.readAsText(fileName);
}

then self points to the input box (as that is the context of the outer method).

So the question is, how do I get the real 'this' object for the FileTools reference.

Thanks.

Noam
  • 197
  • 1
  • 4
  • 13

1 Answers1

4

In ES6 and TypeScript even for class methods the regular function rules for this still apply.

In the start method you are sending a reference to the readSingleFile function as the callback for the change event.That function will later get called in the input field's context thus changing what this points to.

Try using an arrow function instead to preserve the same context.

 start() {
   document.getElementById("file-input").addEventListener("change", e => {
     this.readSingleFile(e); // this should now be FileTools
   }, false);
 }
toskv
  • 30,680
  • 7
  • 72
  • 74
  • Thanks. Can someone explain, or point me to an explanation, why this solution works. why does the arrow function change the scope. – Noam Dec 30 '15 at 17:12
  • This might help clear some things. http://stackoverflow.com/questions/3127429/how-does-the-this-keyword-work – toskv Dec 30 '15 at 17:16