Function inside filereader.onload is not being executed in javascript

filereader, javascript, typescript

Solution

It fails in the onload callback due to changed context (`this`). JavaScript natively change the context in callback. In your case in onload `this` is the same as `reader`. You have to bind right context.

SOLUTION 1 You can bing the right context to passed function by bind method on that function.

getBase64(file: any) {
    var reader: FileReader = new FileReader();
    reader.onload = function (readerEvt: any) {
        var binaryString = readerEvt.target.result;
        this.base64Url = binaryString;
        this.mimeType = this.base64Url.substring(this.base64Url.lastIndexOf("data") + 5, this.base64Url.lastIndexOf(";"));
        this.base64Url = this.base64Url.substring(this.base64Url.lastIndexOf("base64") + 7);
        this.addContentAttachment(this.mimeType, this.base64Url);
    }.bind(this); // We forced that when function will be called this will be current this.

    reader.readAsDataURL(file);

    reader.onerror = function (error) {
        console.log('Error: ', error);
    };

}

SOLUTION 2 The same would be solved by `self` variable in parent scope of callback. We use self variable to store right context and then we use it in callback instead of standard ("corrupted" this).

getBase64(file: any) {
    var reader: FileReader = new FileReader();

    var self = this; // create self with right this
    reader.onload = function (readerEvt: any) {
        var binaryString = readerEvt.target.result;
        self.base64Url = binaryString; // using self instead this
        self.mimeType = self.base64Url.substring(self.base64Url.lastIndexOf("data") + 5, self.base64Url.lastIndexOf(";"));
        self.base64Url = self.base64Url.substring(self.base64Url.lastIndexOf("base64") + 7);
        self.addContentAttachment(self.mimeType, self.base64Url);
    };

    reader.readAsDataURL(file);

    reader.onerror = function (error) {
        console.log('Error: ', error);
    };

}

SOLUTION 3 (thanks to @Aleksey L.) TypeScript can automate solution 2 by their own syntax. You can try that and see result in playground, it does the same as described in solution 2, but variable is named _this instead of self.

getBase64(file: any) {
    var reader: FileReader = new FileReader();
    reader.onload = (readerEvt: any) => {
        var binaryString = readerEvt.target.result;
        this.base64Url = binaryString;
        this.mimeType = this.base64Url.substring(this.base64Url.lastIndexOf("data") + 5, this.base64Url.lastIndexOf(";"));
        this.base64Url = this.base64Url.substring(this.base64Url.lastIndexOf("base64") + 7);
        this.addContentAttachment(this.mimeType, this.base64Url);
    };

    reader.readAsDataURL(file);

    reader.onerror = function (error) {
        console.log('Error: ', error);
    };

}

Problem

I am reading the file using filereader and using the base64 to perform some action. I can read the file and get base64 but couldn't use that to make some action. here is my code. The problem is the code in the line this.addContentAttachment(this.mimeType,this.base64Url) not being executed ``` getBase64(file: any) { var reader:FileReader = new FileReader(); reader.onload = function (readerEvt: any) { var binaryString = readerEvt.target.result; this.base64Url = binaryString; this.mimeType = this.base64Url.substring(this.base64Url.lastIndexOf("data") + 5, this.base64Url.lastIndexOf(";")); this.base64Url = this.base64Url.substring(this.base64Url.lastIndexOf("base64") + 7); this.addContentAttachment(this.mimeType,this.base64Url); }; reader.readAsDataURL(file); reader.onerror = function (error) { console.log('Error: ', error); }; } ```

Original source