Concocting your custom blob in Angular 2 from input may lead to data corruption

For educational purposes, I am looking to utilize the html input tag in order to select a jpeg image, extract the File Object, read it with fileReader, and use the retrieved image string (base64) to generate a new blob/file.

The service successfully uploads the original file obtained from the input. However, when using my newFile, the file becomes corrupted and mysteriously increases in size.

I suspect that there may be an issue with the blob constructor?

I am working with Angular2 in typescript

<input type="file" (change)="onFileChanged($event)">

onFileChanged(event){
    if (event.target.files && event.target.files[0]) {
        let file = event.target.files[0];
        let newFile;
        let fr = new FileReader();
        fr.onload = (event:any)=>{
            let base64 = event.target.result
            let img = base64.split(',')[1]
            let blob = new Blob([window.atob(img)],{type:'image/jpeg'})
            newFile = this.blobToFile(blob,'test')
        }
        fr.readAsDataURL(file)
        console.log(file)
        console.log(newFile)
        this.service.upload(newFile).subscribe()
    }

}

blobToFile(blob: Blob, fileName: string): File {
        let b: any = blob;
        b.lastModified = moment.now();
        b.lastModifiedDate = new Date();
        b.name = fileName;
        b.webkitRelativePath="";
        return <File>blob
    }

EDIT------------ After realizing that fileReader functions asynchronously, I made some adjustments and indeed, the issue lies within the blob constructor. Comparing the target.result of the original file and the new one showed that the base64 has changed. Any thoughts on why?

if (event.target.files && event.target.files[0]) {
            let file = event.target.files[0];
            let base64: string = null;

            if (/^image\//.test(file.type)) {
                let reader = new FileReader();
                reader.onload = (e: any) => {
                    console.log(e.target)
                    base64 = e.target.result

                    let img = base64.split(',')[1];
                    let blob = new Blob([img], { type: 'image/jpeg' })
                    console.log(blob);
                    let fr = new FileReader()
                    fr.onload = (event: any) => {
                        console.log(event.target)
                    }
                    fr.readAsDataURL(blob)
                }
                reader.readAsDataURL(file);
}

Answer №1

To improve your function, make the following modifications. The FileReader functions asynchronously, so you must process the result inside the onload callback. Currently, you are uploading the file outside of onload, where it is either undefined or retains its initial value.

onFileChanged(event){
    if (event.target.files && event.target.files[0]) {
        let file = event.target.files[0];
        let newFile;
        let fr = new FileReader();
        fr.onload = (event:any)=>{
            let base64 = event.target.result
            let img = base64.split(',')[1]
            let blob = new Blob([window.atob(img)],{type:'image/jpeg'})
            newFile = this.blobToFile(blob,'test')
            this.service.upload(newFile).subscribe()
        }
        fr.readAsDataURL(file)
        console.log(file)
        console.log(newFile) // Either prints undefined or whatever initial value it contains

    }

}

Answer №2

It appears that there may be an issue with the code you provided:

onFileChanged(event){
    if (event.target.files && event.target.files[0]) {
        let file = event.target.files[0];
        let newFile;
        let fr = new FileReader();
        fr.onload = (event:any)=>{
            let base64 = event.target.result
            let img = base64.split(',')[1]
            let blob = new Blob([window.atob(img)],{type:'image/jpeg'})
            newFile = this.blobToFile(blob,'test')
        }
        fr.readAsDataURL(file)
        console.log(file)
        console.log(newFile)
        this.service.upload(newFile).subscribe()
    }

}

There seems to be a potential confusion between 'event' in the onFileChanged function and 'event:any' in the FileReader onload event. It's important to differentiate these two instances of 'event' to avoid any cross-referencing issues.

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

The issue of an undefined error in the callback function of a JavaScript Ajax

After searching extensively for a solution to what seems like a common problem, I couldn't find anything that worked for me. So here is my issue: In short, the Razor code I have (shown below) posts an ajax form to an MVC4 action successfully. However ...

Comparing JSON import methods: HTTP vs require

I discovered two methods for importing local json files into my code. Using angulars http get. This method is well-known for loading json input. It provides the flexibility to easily switch between remote and local json files. Typescript require Anot ...

What issue can be identified in this sample of an https.request?

Trying out this specific example always leads to no return whatsoever. const https = require('https') const options = { hostname: 'encrypted.google.com', port: 443, path: '/', method: 'GET', // key: f ...

Ways to minimize the size of Nextjs Static HTML Export page on disk

While utilizing Nextjs Static HTML Export, I've noticed that each page (consisting solely of HTML code) is being generated with a file size of over 100kb on disk. Are there any methods available to decrease the page size on disk? ...

"Guidelines for implementing a post-login redirection to the homepage in React with the latest version of react-router (v

I am facing an issue where I am unable to redirect to the Home Page when I click the "Login" button during my React studies. Despite trying all possible methods for redirects, none of them seem to work. The function that is executed when I click the "logi ...

Transfer the data from one object to another while disregarding any additional properties

I am dealing with 2 objects: person{ name : string gender : string } woman{ name : string } The challenge I face is that I have an object "person" filled with values, and I need to copy those values into a new object "woman" without including the "ge ...

Is it possible to combine several objects into a single array in JavaScript and determine the total number of objects within it?

Here is a snippet of code I am working with: {bloodStores && bloodStores.map((store) => { if ( store.status === "Stock" && store.b ...

Converting Nested JSON Arrays into Separate Objects

We have developed an integration tool that currently generates JSON data in an array of objects structure, which is not compatible with our end application. Although we cannot modify the structure within the Integration tool itself, we can use JavaScript t ...

Issues encountered with the `npm install` command in Azure build pipelines for a simple Angular application

Transferred the GitHub Repository mentioned in this link to Azure Repository. Established the Build Pipeline using Classic Editor, and you can find the YAML Code below: trigger: branches: include: - refs/heads/master jobs: - job: Job_1 display ...

How can we ensure that the slider thumb label is always shown in Angular 16 Material components?

Is there a way to display the thumb label constantly on a material slider? The solution mentioned above does not seem to work with Angular 16 material UI slider. Could you kindly offer an alternative solution for this issue? ...

Having trouble running the server in Node.js

When working with Node.Js, I encountered a specific issue My progress stopped at 6:16 when the instructions mentioned running "node server.js" to open 127.0.0.1:3000, but instead, an error occurred. https://i.sstatic.net/6esE5.png Upon checking my brows ...

What is the method to modify the background color of el-pagination?

I am using el-pagination on a dark page and I want to make its background color transparent. When I do not use the 'background' prop, the background color of el-pagination is white. Here is how it looks: (sorry I can't add an image) htt ...

Optimal strategies for managing request and response within an Express application

I've developed a REST API using express (and typescript) with the following structure: app.ts routes controllers models Query: Where is the ideal location to handle and construct requests/responses? Is it in routes or controllers? I am ...

Converting a string to Time format using JavaScript

I am working with a time format of 2h 34m 22s which I need to parse as 02:34:22. Currently, I am achieving this using the following code: const splitterArray = '2h 34m 22s'.split(' '); let h = '00', m = '00', s = &a ...

Three.js Orbit Controls effortlessly track the mouse movements without requiring any clicks

Is there a way to modify the orbit controls in three.js to move the scene on mousemove rather than click + mousemove? I tried implementing the solution provided in this thread: How to recreate the Three.js OrbitControl movement on mouse move? However, I en ...

Cluster execution error encountered while utilizing Google Maps in Node.js

Recently, I have started using the node.js platform and I am looking to integrate the googlemap cluster library into my project. However, I am facing issues while trying to run the source code. If you want to explore the googlemaps cluster API, you can fi ...

Rendering on the server using react-router v4 and express.js

I've been working on implementing server-side rendering with the latest version of react-router v.4. I found a tutorial that I followed at this link: . However, when I refresh the browser, I encounter the following error: Invariant Violation: React.C ...

The Properties of a Firestore Document are not being correctly retrieved by the DocumentReference in Typescript

I am currently working on a Firebase Cloud Function that is responsible for creating a new Firestore document and then sending back the unique ID of the document to a Flutter application. My functions are written in Typescript. Below is the code snippet t ...

What steps should be taken to handle files in the Next JS api?

My goal is to send a docx file to the browser for client preview. I've attempted two methods: const rs = fs.createReadStream(fullPath); res.setHeader("Content-Type", "application/vnd.openxmlformats-officedocument.wordprocessingml.docume ...

What is the syntax for passing a generic type to an anonymous function in a TypeScript TSX file?

The issue lies with the function below, which is causing a failure within a .tsx file: export const enhanceComponent = <T>(Component: React.ComponentType<T>) => (props: any) => ( <customContext.Consumer> {addCustomData => ...