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);
};
}
this). JavaScript natively change the context in callback. In your case in onloadthisis the same asreader. You have to bind right context.reader.onload = function () { ... }.bind(this);reader.onload = (readerEvt: any) => { ... }