I am using FileReader
in typescript to convert a blob to a base64 image that will then be displayed in the template of my application.
adaptResultToBase64(res: Blob): string {
let imageToDisplay : string | ArrayBuffer | null = '';
const reader = new FileReader();
reader.onloadend = function () {
imageToDisplay = reader.result;
return imageToDisplay;
};
reader.readAsDataURL(res);
return imageToDisplay;
}
Whilst the data logged inside the read.onloadend
function displays the base64 string I cannot pass it out of the function.
I have tried adding a callback but where it is called elsewhere doesn't return anything but an empty string.
CodePudding user response:
Please check this code
<input type="file" id="file">
<button id="click">click</button>
let data: string | ArrayBuffer;
document.getElementById('file').onchange = function (e: Event) {
let files: FileList | null = (<HTMLInputElement>e.target).files;
let reader: FileReader = new FileReader();
reader.onload = function (e: ProgressEvent<FileReader>) {
console.log(e.target.result);
data = e.target.result;
};
if (files.length > 0) {
reader.readAsDataURL(files?.[0]);
}
};
document.getElementById('click').onclick = function () {
console.log(data); // result if present otherwise null is returned
};
Using a separate method view. The return
value is a Promise
.
function adaptResultToBase64(res: Blob): Promise<string> {
let reader: FileReader = new FileReader();
return new Promise((resolve, reject) => {
reader.onloadend = () => {
resolve(reader.result as string);
}
reader.onerror = () => {
reject("Error reading file.");
}
reader.readAsDataURL(res);
})
}
To get the result
adaptResultToBase64(/* Blob value */)
.then(resp => console.log(resp))
.catch(error => console.log(error));
See here for specifics on Promise
CodePudding user response:
The basic result I needed and did not realise that the reader.onload
is actually a callback for read.readAsDataUrl
and finishes everything inside it async.
adaptResultToBase64(res:Blob){
const reader = new FileReader();
reader.onload = function () {
// Was missing code here that needed to be called asynchronously.
adapterToNewObject(reader.result.toString())
};
reader.readAsDataURL(res);
}
}
I was performing this in Angular so for anyone else who runs into this problem here it is using Angular syntax:
In your class:
export class Component {
adaptedResult:Result
getBase64() {
this.http.get().subscribe((result: Blob) => {
const reader = new FileReader();
reader.onload = () => {
this.adaptedResult = this.adapter(reader.result) // Assign or use reader.result value, this is an example of using an adapter function.
};
reader.readAsDataURL(result);
});
}
adapter(base64:string){
return {
name:'image',
image:base64'
}
}
}