JavaScript's Blob to Base64 conversion using FileReader is failing to produce any output

In my typescript application, I am utilizing the FileReader to convert a blob into a base64 image for display within the template.

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

Even though the base64 string is correctly displayed inside the read.onloadend function, I encounter difficulty passing it out of the function scope.

I attempted using a callback but encountered issues where it returned an empty string when called elsewhere.

Answer №1

Kindly Review and Verify this Code Snippet

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


Incorporating a Distinct Method for Viewing Results. The return Outcome is in the Form of a Promise.

function convertResultToBase64(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 Obtain the Final Output

convertResultToBase64(/* Provide Blob value */)
    .then(resp => console.log(resp))
    .catch(error => console.log(error));

For Detailed Information on Promise, Refer to:

MDN
learn.javascript.ru

Answer №2

After encountering an issue, I discovered that the reader.onload function serves as a callback for read.readAsDataUrl and executes everything inside it asynchronously.

adaptResultToBase64(res:Blob){

    const reader = new FileReader();

    reader.onload = function () {
      
    // There was missing code here that needed to be called asynchronously. 
    
    adapterToNewObject(reader.result.toString())

    };

    reader.readAsDataURL(res);

  }
}

My experience involved working with Angular, so I am sharing my solution for anyone facing a similar problem 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'
   }
 }

}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Breaking apart field values in React Final Form

In my react and redux application, I am using react final form with a 'cars' field that is a select. When the submit event is triggered, it should only return specific types like coupe: ['BMW'] instead of just the field name with values ...

Guide to customizing the layout preview specifically for certain components in Storybook, without affecting all components

Currently working on my storybook project and facing an issue. I'm aiming to have the layout centered in the preview section. I attempted export const parameters = { layout: 'centered', }; in the .storybook/preview.js file However, this c ...

Is sending a stream to a variable the best option, or could there be another solution

Is there a way to pipe stream data to a variable? The writable stream examples mentioned in this documentation include: HTTP requests on the client side HTTP responses on the server side Zlib streams Crypto streams TCP sockets Child process stdin Process ...

"Extracting information from the axios header and passing it to a Vue component: A step-by-step

I am working with an axios apiClient and trying to retrieve the email stored in localStorage to use in the header of my component. I attempted to access the email by using response.headers['email'] and storing it in a variable called email, but ...

Exploring Angular 6's nested routes and corresponding components for child navigation

I'm currently diving into the concept of lazy loading in Angular 6. Here's a visual representation of the structure of my application: ─src ├───app │ ├───components │ │ ├───about │ │ ├─── ...

What is the method for displaying html files in a POST request?

This is the code snippet I am working with: app.post('/convert', function(req,res){ var auxiliar = "somo Ubuntu command line(this works)"; exec(auxiliar, function(err, stdout, stderr){ if(err){ console.log ...

The fade-in effect will initiate from the start once the mouse leaves the element (with a

Currently, I am in search of a solution for improving the navigation menu I am developing. By clicking on this JSFiddle link, you can view the code in action. The issue I am facing is that the fadeIn effect should only occur when hovering over the nav-ite ...

What is the best way to target changing elements displayed by *ngIf?

Trying to access a dynamic element generated by ngIf in the code below has proven to be challenging. I attempted two different methods: Using ElementRef and querySelector Component template: `<div class="test" *ngIf="expr"> <a id="b ...

Accessing an object's property within a mapped array in a Next.js application is possible

Currently, I am attempting to iterate through an array of objects and extract the link property as a <li></li> element. However, I am facing an issue where nothing is being returned: import { useState, useEffect } from "react"; import ...

An in-depth guide on incorporating an Editor into a Reactjs project

Currently, I am working with Reactjs and using the Nextjs framework. My goal is to integrate the "Tinymce" editor into my project and retrieve the editor value inside a formsubmit function. How can I achieve this? Below is my current code: const editor = ...

Modifying the content in one form field based on the information entered in another input field

I have a scheduling application that includes a form for selecting both the departure city and arrival city. The app is designed for international travel only, so when a user selects a city from Hungary as the departure city, I want to exclude all Hungaria ...

Compare the precise value of $(window).height() to a specific scroll value

Initially, I retrieve $(window).height() and compare this height with the specific scroll value. $(window).scroll(function (event) { var scroll = $(window).scrollTop(); var windowHeight = $(window).height(); console.log("window hei ...

Is there a way to resize SVG images without having to modify the underlying source code?

Within my Vue Single File Component, there is a prop labeled svg, which holds a string of SVG markup like <svg>...</svg>. What is the best way to render and resize this SVG content? ...

Show a separate div in a block format if the data field contains a value

<span>{{pstCtrl.doctorProfile.boardCertification ? === 'Yes' : $yes.display-block}}</span> <span class="yes">Yes</span> span.yes { display:none; } In my Angular.JS project, the code snippet above is demonstra ...

Typescript does not allow for extending an interface with a data property even if both interfaces have the same data type

I've encountered a peculiar problem with Typescript (using Visual Studio 2012 and TypeScript v0.9.5) that I could use some help clarifying. The code snippet below functions correctly: interface IA { data: any; } interface IB { data: any; } ...

What is the best way to pass an array of 8-digit strings from an input in Angular to a Node.js backend?

I am currently facing a challenge where I need to pass an array of 8 digit strings from an Angular input to a Node.js endpoint. The method below works perfectly fine when passing a single string, but how can I handle an array of 8 digit strings as input? ...

Sending a collection of nested arrays to an MVC controller

Currently, I am utilizing spring MVC and have the requirement to transmit data to my controller on the backend server. @RequestMapping(value="/project/update") public @ResponseBody projectWebForm update(HttpServletRequest request, HttpServletRespo ...

Retrieving outcomes from a sequence of callback functions in Node.Js

I've been struggling to get my exports function in Node.Js / Express app to return the desired value after going through a series of callback functions. I've spent hours trying to fix it with no success. Can someone provide some guidance? Here is ...

Guide to organizing an HTML table column with a header click using PHP and MySQL

I am currently working on a table that displays data from a MySQL database. I would like to implement functionality that allows users to click on certain columns to sort them in ascending or descending order. However, I am unsure of whether to use PHP, H ...

Is there a way to trigger the click event in the week view of an Angular 2+ calendar?

https://i.sstatic.net/Vx2x8.png HTML Templates <mwl-calendar-week-view [viewDate]="viewDate" [refresh]="refresh" (click)="weekDayClick($event)"> </mwl-calendar-week-view> In the component file weekDayCl ...