Monitoring separate upload progress within $q.all() in AngularJS

I recently started using the angular-file-upload module created by danialfarid (https://github.com/danialfarid/angular-file-upload) and I must say, it's been a great experience so far.

After successfully integrating it into my wrapper service for REST calls, I have managed to upload multiple images simultaneously using $q.all() while monitoring their progress.

Despite this success, I've encountered an issue where I'm unable to properly identify individual images during the upload process because the file identifier keeps getting changed within the for loop.

      uploadPhotos: function (files) {

        var deferred = $q.defer()
        var queue = []

        for (var i = 0; i < files.length; i++) {
          var file = files[i];
          var up = $upload.upload({
            url: locationURI +'/photos',
            file: file,
            fileFormDataName: 'image'
          }).then(
            function (data) {
              console.log(data)
            },
            function (err) {
              console.log(err)
            },
            function(evt) {
              // progress events
              console.log('percent: ' + parseInt(100.0 * evt.loaded / evt.total));
            }
          )
          queue.push(up)
        }

        $q.all(queue).then(
          function (data) {
            deferred.resolve(data)
          },
          function (err) {
            deferred.reject(err)
          }
        )

        return deferred.promise
      }

Unfortunately, the output I'm currently seeing is quite confusing:

    percent: 68 restfactory.js:359
    percent: 100 restfactory.js:359
    percent: 100 restfactory.js:359
    percent: 14 restfactory.js:359
    percent: 37 restfactory.js:359
    percent: 52 restfactory.js:359
    percent: 89 restfactory.js:359
    percent: 100 restfactory.js:359
    percent: 100 restfactory.js:359

Is there any solution you can suggest to help me achieve a clearer output like this:

    file1 - percent: 68 restfactory.js:359
    file1 - percent: 100 restfactory.js:359
    file2 - percent: 100 restfactory.js:359

Answer №1

Working with closures within loops can be challenging. If you close on the loop variable, it will always retrieve the last value. Instead, consider calling another function within the loop:

for (var i = 0; i < files.length; i++) {
    var upload = performUpload(files[i]);
    queue.push(upload);
}

The performUpload() function should contain your original code, returning the promise and utilizing the correct file (assuming file.name contains the file name):

function performUpload(file) {
      var upload = $upload.upload({
        url: locationURI +'/photos',
        file: file,
        fileFormDataName: 'image'
      }).then(
        function (data) {
          console.log(data)
        },
        function (err) {
          console.log(err)
        },
        function(evt) {
          // progress events
          console.log(file.name + ' percent: ' + parseInt(100.0 * evt.loaded / evt.total));
        }
      );
      return upload;
}

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

Place the div directly beside the input field on the right side

I am attempting to align a div directly beside the text being entered in a text input field. It seems logical to me that this could be achieved by measuring the length of the input value and positioning the div accordingly. However, the issue I am facing i ...

Integrating custom HTTP headers with window.location.href in an Angular application

I encountered a situation with my Angular app where I needed to redirect it to a non-angular HTML page. My initial thought was to use $window.location.href to achieve this redirection successfully. However, the challenge arose when I realized that my Node. ...

Unable to set a JSON data as a value for a JavaScript variable

I am currently developing a YT mp3 downloader using the API provided by youtubeinmp3. I have been successful in obtaining the download link in JSON format. https://i.stack.imgur.com/3mxF2.png To assign the value of "link" from the JSON to a JavaScript va ...

What is the best way to alternate between two CSS stylesheets when using jQuery-UI?

Just getting started with jQuery and javascript and decided to test out 2 different jQuery-ui stylesheets in a simple .html file. The goal is to have the example dialog open with the "flick" stylesheet and the datepicker within the dialog open with the "u ...

What role does the @Input statement in the HeroDetailComponent class serve in the Angular 2 Quickstart tutorial?

Looking at the multiple components part of the Angular 2 Quickstart tutorial, we see how a component is separated from the AppComponent to enhance reusability and testing convenience. You can try out the example live demo here. In this scenario, users ar ...

When scrolling, use the .scrollTop() function which includes a conditional statement that

As a newcomer to jQuery, I've been making progress but have hit a roadblock with this code: $(window).scroll(function(){ var $header = $('#header'); var $st = $(this).scrollTop(); console.log($st); if ($st < 250) { ...

What is the best way to incorporate multiple countdown timers on a single HTML page?

I am in the process of developing an online auction site and I need to include the end time and date for each auction. To achieve this, I have created a countdown.js file with the following code: // set the date we're counting down to var target_dat ...

Guide to including a promise.map (bluebird) within a nested promise chain

I'm currently using a chain to control flow and struggling to make promise.map within step2() wait for all generated promises to be resolved. Here's a visual representation of the flow I aim for: step1() step2() step2() ste ...

StyledTab element unable to receive To or component attributes

Is there a way to use tabs as links within a styled tab component? I've tried using the Tab component syntax with links, but it doesn't seem to work in this scenario: <Tab value="..." component={Link} to="/"> If I have ...

Accumulation of style from various directives in AngularJS on a single element

Currently, I am working on developing a component framework and find myself in need of a method to apply styles from multiple directives to an element in a way that they can accumulate. The priority of the styles should be determined by the directive creat ...

Discover the Power of AngularJS – Master the Art of Toggling Classes

Instructions scope.pauseClass = 'fa fa-pause'; scope.muteClass = 'fa fa-volume-on'; <button ng-click="doPlayOrPause(uniqId)"><i ng-class="pauseClass"></i></button> <button ng-click="doMute(uniqId)"><i ...

Looking to conduct date comparisons within angular-ui-grid?

I'm currently working on an application that utilizes angular-ui-grid to display form data. One issue I'm facing is how to compare the submission date obtained from an API call with the current date within ui-grid, in order to calculate the numbe ...

Required Field Validation - Ensuring a Field is Mandatory Based on Property Length Exceeding 0

When dealing with a form that includes lists of countries and provinces, there are specific rules to follow: The country field/select must be filled out (required). If a user selects a country that has provinces, an API call will fetch the list of provinc ...

Adjustable textarea with automatic height based on content and line breaks

Imagine you have a textarea with text that includes line breaks. If you style it like this: textarea { height: auto; overflow: hidden; resize: none; } Upon loading the page, the textarea will only adjust its height based on the content until it enc ...

Can anyone tell me the Ionic framework's counterpart to Android Webview?

Recently, I designed a unique IONIC/Angular JS application and I am currently exploring various ways to enhance its features. One particular feature that I have been contemplating is the ability to load a web page within my application, similar to how it ...

Is your Discord bot failing to log on?

I created a discord bot, but I'm having trouble getting it online. There are no errors and I'm not sure why. Here is my code: const TOKEN = "MyBotsToken"; const fs = require('fs') const Discord = require('discord.js'); const C ...

Guide to sending multiple forms from an HTML page to another PHP page

What is the best way to submit multiple forms on a single HTML page to a PHP page and process all the form elements in PHP upon clicking one button? Any suggestions are appreciated. Thank you in advance. <form id="form1" name="form1"action="abc.php" ...

Updating JSON Data Retrieved from C# AJAX Request

During my ajax call, I am fetching JSON data that is being returned from a query. The current JSON response looks like this: [{ "label": "", "value": "2302" }, { "label": "9 - Contract set-up in EPICOR", "value": "2280" }, { "label": " ...

Getting data from jquery.ajax() in PHP - A comprehensive guide

When transferring data from JavaScript to PHP, I use the following method: $.ajax({'url': 'my.php', 'type': 'POST', 'data': JSON.stringify(update_data), 'success': functio ...

Exploring Angular 2 Beta 8: An Introduction to @Query Usage

My attempt to utilize @Query to fetch data regarding an element in my template has not been successful. I made an effort using the following approach: Referenced here. Here is a snippet of my code, import {Component, Query, QueryList, ElementRef} from &a ...