Javascript FileReader encountering asynchronous problem

After uploading a file in my application, I need to verify the file type by checking both the extension and including a magic bytes check. To accomplish this, I found a helpful article at:

https://medium.com/the-everyday-developer/detect-file-mime-type-using-magic-numbers-and-javascript-16bc513d4e1e

Below is the code for my verification method:

checkFileTypeViaMagicByte(file):boolean {

  const filereader = new FileReader();
  const blob = file.slice(0, 4);
  filereader.readAsArrayBuffer(blob);

  filereader.onloadend= (evt) => {
    if (evt.target.readyState === FileReader.DONE) {
    // @ts-ignore
    const uint = new Uint8Array(evt.target.result);
    let bytes = []
    uint.forEach((byte) => {
      bytes.push(byte.toString(16))
    })
    const hex = bytes.join('').toUpperCase();
    console.log("SIGNATURE: " + hex);
    switch (hex) {
      case '89504E47': //image/png
        return true;
      case '25504446'://application/pdf
        console.log("PDF case");
        return true;
      case 'FFD8FFDB'://image/jpeg
      case 'FFD8FFE0':
       return true;
      default:
        return false;
    }

  };

};
 return false;
}

The challenge I'm facing is that FileReader operates asynchronously and my method always returns false. Since I have multiple methods performing checks like allowed filenames and file sizes, I need to address this issue within a method. How can I resolve this problem?

Answer №1

To make the filereader.onloadend function work, you just need to turn it into a promise.

checkFileTypeViaMagicByte(file):boolean {
    const filereader = new FileReader();
    const blob = file.slice(0, 4);
    filereader.readAsArrayBuffer(blob);
    return new Promise((resolve, reject) => {
        filereader.onloadend = (evt) => {
            try {
                if (evt.target.readyState === FileReader.DONE) {
                    // @ts-ignore
                    const uint = new Uint8Array(evt.target.result);
                    let bytes = [];
                    uint.forEach((byte) => {
                        bytes.push(byte.toString(16));
                    });
                    const hex = bytes.join("").toUpperCase();
                    switch (hex) {
                        case "89504E47": //image/png
                            resolve(true);
                            break;
                        case "25504446": //application/pdf
                            resolve(true);
                            break;
                        case "FFD8FFDB": //image/jpeg
                        case "FFD8FFE0":
                            resolve(true);
                            break;
                        default:
                            resolve(false);
                    }
                }
            } catch (err) {
                reject(err);
            }
        };
    });
}

This function will give you a boolean value as a promise, which you can handle using then.

checkFileTypeViaMagicByte(file).then(res => console.log(res))

Alternatively, you can use the await/async syntax.

(async () => {
   const result = checkFileTypeViaMagicByte(file)
   console.log(result)
})()

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

Struggling to move forward with developing a task management app due to a roadblock

I am seeking guidance rather than a direct answer, as this is crucial for my final exam. I require a starting point to help me fill in the missing pieces. It's important to note that local storage cannot be used to store user input. // POST handler ad ...

Problem with sending data using $.ajax

I stumbled upon a strange issue. In one of my php pages, I have the following simple code snippet: echo $_POST["donaldduck"]; Additionally, there is a script included which makes a $.ajax call to this php page. $.ajax({ url: "http://provawhis ...

Encountering an Unknown Error when attempting to retrieve a response using Angular's httpClient with

The Service.ts file contains the following code: public welcome(token: any){ let tokenString = "Bearer "+token console.log("tokenString is: "+tokenString) let header = new HttpHeaders().set("Authorization",tokenSt ...

The shade of grey on the curve appears instead of the usual red on the iPad. Any ideas on how to fix

I am having trouble creating a curve like the one shown below on my iPad. The color appears to be gray and does not work properly. Is this a bug with ChartJS or is there a solution to fix this issue? This problem occurs when the type value is set to "lin ...

"Exploring the World of Android WebView with JavaScript

My app has a minimum API of 16, and I need to run some javascript on a web view. However, when I try to use mWebView.evaluateJavascript("(function()...)"); I receive a compile error indicating that this feature is only available in API 19 and higher. Ho ...

Steps for creating new users using a post request

I've been working on developing a chat application using react-chat-engine, and everything is running smoothly except for one issue - I'm struggling to figure out how to send a post request to create new users. Below is the code snippet I'v ...

The file name is not compatible with 'eslint' functionality

I attempted to use the solution provided in this Stack Overflow thread for the error message 'eslint' is not recognized as an internal or external command. I successfully created a .eslintrc.json file with the following content: { "extends" ...

The error message "@types/d3" states that the type 'Area<X>' cannot be assigned to the type 'String'

Within a typescript class, I have a method instance... createArea = d3.area<Point>().x((d) => d.x).y0((d) => d.max).y1((d) => d.y); Although this method works fine, it is being seen as an instance field. To rectify this, I tried adding a t ...

Are union types strictly enforced?

Is it expected for this to not work as intended? class Animal { } class Person { } type MyUnion = Number | Person; var list: Array<MyUnion> = [ "aaa", 2, new Animal() ]; // Is this supposed to fail? var x: MyUnion = "jjj"; // Should this actually ...

Creating a flexible regular expression in MongoDB: A step-by-step guide

I've created a regular expression to match terms containing a specific phrase, which may include letters or numbers but excludes dashes. For example, the regex ^[test0-9._-]+$/gi will successfully match terms like test-123, test123, and test. However ...

Use jQuery to apply a class to some input elements when certain events like keyup or

If I type something in the input field, it should add a border to the li tag containing the text. The current script works fine, but is there a way to make this jQuery script shorter? Thank you for your help! .add_border{ border: 2px solid #000 !impor ...

When using NodeJS, having multiple 'if' statements may result in conflicting headers being returned,

Introduction to Promises. Encountering challenges in NodeJS due to the utilization of multiple if-statements and return-statements. Considering leveraging Promise as a potential solution. This snippet showcases an example: const express = require(' ...

Is there a way to generate a modal list of values by utilizing bootstrap and angular, while incorporating spring boot as the backend technology?

I'm working on developing a generic "List of Values" feature, which will be a searchable modal containing a natural identifier and description. I have successfully built an AngularJS application in Spring Boot to accomplish this task, but unfortunatel ...

Empty Ajax array sent to PHP

I am encountering an issue with my ajax form where the values in an array are coming out as null in my PHP response. I suspect that there may be a mistake in my .ajax call. Can anyone provide suggestions or insights on how to resolve this issue? My code sn ...

Is there a way to prevent the variable from being trapped in the first option when using an if/else if statement?

Below is my JavaScript code snippet: let x = Math.floor(Math.random() * 6) + 1); if (x == 1){ do this } else if (x == 2){ do that } else if.... and so on. Every time I run this code in a browser, only actions related to the {do this} section seem ...

Creating an array object in JavaScript is a straightforward process that involves using the array

Looking to achieve the following object list structure: myObj = {"foo":[1,2,3,4], "bar":[3,5,7,8]} Initial attempt was unsuccessful: var myObj = new Object(); myObj["foo"].push(1) myObj["foo"].push(2) #...etc Seeking guidance on the correct m ...

The 'Content-Type' header cannot be defined for HTTP GET requests

I am currently working on setting up my GET requests to include the specific header: Content-Type: application/json Based on information from the documentation, I need to make the following adjustment: To customize these defaults, you can add or remov ...

Verification of Passport

I am currently working on developing a passport validation system that is dependent on the format of the passport. I have created two input bars, with the first bar only allowing users to input 2 letters and the second bar only accepting 7 numbers. Can any ...

Incorporating a dynamic Sublime HTML5 Video player into your website

Struggling to dynamically load a series of sublime videos on my website, I'm facing issues distinguishing between the 'sublime' and 'sublimevideo' objects. Unfortunately, the documentation isn't offering much help. Here' ...

Extract information from a JSON string stored in a variable and transform it into objects within the $scope.variable

I currently have a string variable that contains JSON data displayed below. var jsonstring = [{"latitude":"51.5263","longitude":"-0.120285","altitude":"","device":"123","rating":"5","region":"Europe","customer":"","time":"1-2 Weeks","error":"Error 1","app ...