I encountered an issue with my TypeScript function in Angular, as it is unable to process multiple uploaded files

I'm having trouble with my TypeScript function in Angular that is unable to read multiple uploaded files.

fileUpload(event: Event) {
    const self = this;
    this.imageUploadInp = event.target as HTMLInputElement;
    this.imageUploadInp.addEventListener("change", function () {
        for (var i = 0; i < self.imageUploadInp.files.length; i++) {
            var reader = new FileReader();
            reader.onload = function () {  
                if (reader.result != undefined) {
                    self.user.imgUrls = reader.result.toString();
                    console.log(self.user.imgUrls);
                }
            }
            reader.readAsDataURL(self.imageUploadInp.files[i]);  
        }
    });
}

Answer №1

The issue arises from the fact that the onload handler is executing asynchronously while you are constantly overwriting the reader variable within the synchronous for loop. As the for loop operates synchronously, the onload callback will only run in the subsequent cycle of the event loop. Due to variables declared with var having function scope, the reader variable in the handler function will solely reference the last image, leading to only the final image being processed.

Given your use of typescript, it's presumed that you can utilize the const/let keywords. To rectify your code, consider declaring the reader variable as const or let. Variables declared with const or let have block scope, creating new blocks on each cycle of the for loop, preventing them from overriding each other and existing independently within their respective blocks.

fileUpload(event: Event) {
    const self = this;
    this.imageUploadInp = event.target as HTMLInputElement;
    this.imageUploadInp.addEventListener("change", function () {
        for (let i = 0; i < self.imageUploadInp.files.length; i++) {
            const reader = new FileReader(); // declared as `const`
            reader.onload = function () {  
                if (reader.result != undefined) {
                    self.user.imgUrls = reader.result.toString();
                    console.log(self.user.imgUrls);
                }
            }
            reader.readAsDataURL(self.imageUploadInp.files[i]);  
        }
    });
}

I've also changed the declaration of the i variable to let within the for loop. This decision ensures that any use of the var i variable inside the onload handler won't face the same fate as the var reader, which becomes equal to

self.imageUploadInp.files.length - 1
after the completion of the for loop.

If circumstances prevent you from using let/const, another approach involves creating unique functions for each cycle of the for loop to encapsulate var reader within different function scopes:

fileUpload(event: Event) {
    const self = this;
    this.imageUploadInp = event.target as HTMLInputElement;
    this.imageUploadInp.addEventListener("change", function () {
        for (var i = 0; i < self.imageUploadInp.files.length; i++) {
            (function () { // creating different function scopes on each cycle
                var reader = new FileReader();
                reader.onload = function () {  
                    if (reader.result != undefined) {
                        self.user.imgUrls = reader.result.toString();
                        console.log(self.user.imgUrls);
                    }
                }
                reader.readAsDataURL(self.imageUploadInp.files[i]);
            }());  
        }
    });
}

In this updated version, I've utilized the IIFE pattern to isolate each reader variable created in the for loop within its distinct function scope.

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

WebStorm lacks support for TypeScript's `enum` and `readonly` features

When working with TypeScript in WebStorm, I encountered an issue where the IDE does not recognize enum or readonly. To solve this problem, I delved into TypeScript configuration files. I am currently utilizing .eslintignore, .eslintrc, tsconfig.json, and ...

Is there a way to automatically close the previous accordion when scrolling to a new one on the page?

Currently, I am working with the material-ui accordion component and facing an issue where all accordions are initially opened. As I scroll down the page and reach a new accordion, I want the previous ones to automatically close. The problem arises when tr ...

Obtaining specific information about the target item that a source item was dropped on (using ng2-dragula in Angular)

Issue: I need assistance in implementing the following functionality using the ng2-dragula drag behavior. I am working on creating a feature similar to the app-launcher found on iOS and Android devices. I aim to drag an item A and drop it onto anothe ...

Is it necessary to also include template-only attributes in my controller's definition?

I'm working on a directive template that features a basic toggle variable. <div ng-mouseenter="$ctrl.myToggle = true" ng-mouseleave="$ctrl.myToggle = false"> ... </div> <div ng-if="$ctrl.myToggle"> ... toggled content </div> ...

The list of countries does not appear in the NgxIntlTelInput plugin for Angular

I am encountering an issue with the Country list not showing in my form while using NgxIntlTelInput Angular plugin to input a telephone number along with the country code. Here is the relevant code snippet: <form #f="ngForm" [formGroup]=" ...

What is the process of personalizing a DaisyUI theme in Tailwind with TypeScript?

I am trying to tailor an existing DaisyUI theme using my tailwind.config.ts file for my Next.js project. Although the DaisyUI documentation only provides examples in JavaScript (text), I want to customize it within my TypeScript environment. Below is a s ...

Cookie authentication in CodeIgniter with Angular HTTP requests in Ionic 3

I am experiencing difficulties sending POST/get requests to the server. When using the Postman Chrome extension, everything works fine. However, when attempting to use Angular Http (not HttpClient) in Ionic, I encounter errors. The first error is related t ...

Creating a generic class for third-party API requests in NestJS

I'm working on a NestJS application that involves making third-party API requests. Every function requires the same code to retrieve data, causing repetition. How can I streamline this process by creating a common class for handling GET or POST reque ...

Error in Typescript Observable when using .startWith([])

I encountered the TypeScript error below: Error:(34, 20) TS2345: Argument of type 'undefined[]' is not assignable to parameter of type 'number | Scheduler'. Type 'undefined[]' is not assignable to type 'Scheduler& ...

What is the most effective method to create a versatile function in Angular that can modify the values of numerous ngModel bindings simultaneously?

After working with Angular for a few weeks, I came across a problem that has me stumped. On a page, I have a list of about 100 button inputs, each representing a different value in my database. I've linked these inputs to models as shown in this snipp ...

Using an AWS API Gateway, an HTTP client sends a request to access resources

I have a frontend application built with Angular and TypeScript where I need to make an HTTP request to an AWS API Gateway. The challenge is converting the existing JavaScript code into TypeScript and successfully sending the HTTP request. The AWS API gat ...

The element is implicitly assigned an 'any' type due to the fact that an expression of type 'any' cannot be used to index types in nodejs and solidity

I am in need of setting networks in my contract using NodeJS and TypeScript. Below is the code I have written: let networkId: any = await global.web3.eth.net.getId(); let tetherData = await Tether.networks[networkId]; Unfortunately, I encountered ...

Create a new WebSocket package for Node.js that allows for segregating connections into

I am currently exploring ways to implement a feature similar to "rooms" using the npm 'ws' package, inspired by how rooms function in socket.io. I want to avoid using socket.io, but I am faced with the challenge of retrieving user/room informatio ...

How to include an image in a file type using Angular 2 and TypeScript

Is it possible to assign an image to a file type variable in Angular 2? I attempted the following approach: private file:File; setImage(){ this.file = "../assets/image/image.jpg" } Unfortunately, this method did not succeed. ...

Issue encountered while trying to determine the Angular version due to errors in the development packages

My ng command is displaying the following version details: Angular CLI: 10.2.0 Node: 12.16.3 OS: win32 x64 Angular: <error> ... animations, cdk, common, compiler, compiler-cli, core, forms ... language-service, material, platform-browser ... platfor ...

Discover which references are yet to be resolved within a tsx file

I have been tasked with developing a custom builder for a web application. The challenge now is to automatically detect imports in the code so that the right modules can be imported. My current solution involves traversing the AST of the scripts, keeping ...

Is Webpack CLI causing issues when trying to run it on a .ts file without giving any error

I am facing an issue with my webpack.config.js file that has a default entrypoint specified. Here is the snippet of the configuration: module.exports = { entry: { main: path.resolve('./src/main.ts'), }, module: { rules: [ { ...

When making Angular GET requests, the response may return a single Object instead of an Array

When making a GET request to my API, the data is returned as Objects inside an Object instead of an Array of Objects. This makes it difficult for me to iterate through and print the data. I am puzzled by why this specific request is behaving differently c ...

Sort by the recent messages of another observable

I'm attempting to sort through messages in one observable based on the messages from another observable. navCmds --A----B---C--A------D-----------------C-----D----E---> navNotifications ----A----X---B-C-A---D------------------------DCA-- ...

Guide to incorporating Angular 2 onto a specific section of a webpage

As a student of Angular 2, I have a question about utilizing specific parts of a web page. Is it possible to use certain Angular 2 utilities, such as *ngFor, in only designated areas - for example, within just a div element? While this was feasible in An ...