1

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.

2
  • 2
    Does this answer your question? (rhetorical) How do I return the response from an asynchronous call? Commented Jan 24, 2023 at 17:28
  • A very good explanation of all things async, but it turns out poor explanations and documentation on the specific thing I needed was more my issue! Commented Jan 25, 2023 at 15:45

2 Answers 2

2

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

MDN
learn.javascript.ru

Sign up to request clarification or add additional context in comments.

2 Comments

This is good, but I'm not calling the function in the DOM. I'm getting the base64 from another file and using it elsewhere.
Well, I think I understand you. Look here
0

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'
   }
 }

}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.