cordovaFileTransfer wait for progress to reach 100

I would like to have a real time progress bar while downloading a file. Right now, I managed to show the error pop up in case of error. But, I cant synchronize the success and progress pop-ups. The scenario is, while starting the download process, a pop-up with a progress bar should be shown untill the download progress reach 100%. Once the download is finished, the progress pop-up should be closed, and a success pop-up should be shown for a few seconds and then dissapear.

I managed to show the progress bar, and get somehow real time progress values. But when the progress reaches 100%, the pop-up is till shown. A solution that came into my mind (I dont know if its correct) is to make the .then(function(result) to wait for a promise from the function(progress). So, it will wait for it to finish and show the success pop up. If I put the success pop-up code in the .then(function(result) , then, this pop-up will be shown first and then the progress. Which is not ideal. Any thoughts:

   if ($scope.isOnline()) {
    var url = 'http://example.com/file.pdf';
    var targetPath = cordova.file.externalDataDirectory + "file.pdf";
    var trustHosts = true;
    var options = {};

    $http({
      method: 'GET',
      url: url
     })
     .success(function(data, status, headers, config) {
      console.log("I see the file");

      $cordovaFileTransfer.download(url, targetPath, options, trustHosts)
       .then(function(result) {
        console.log("File downloading");
        console.log(targetPath);

        if ($scope.downloadProgress >= 100) {
          console.log("Downloaded");
        }

        var progressPopup = $ionicPopup.show({
           scope: $scope,
           title: 'Downloading..',
           templateUrl: 'download-progress.html'
          });

       }, function(err) {
        console.log(err);

        var errorPopup = $ionicPopup.show({
         scope: $scope,
         title: 'Download Failed',
         templateUrl: 'download-error.html'
        });

        $timeout(function() {
         errorPopup.close();
        }, 3000);

       }, function(progress) {
        //This function is repeated while the file is downloaded
        if ($scope.downloadProgress != 100) {
         $timeout(function() {
          $scope.downloadProgress = Math.round((progress.loaded / progress.total) * 100);
          console.log($scope.downloadProgress);
         }, 500);
        }
       });
     })

     .error(function(data, status, headers, config) {
      //If the file is not reachable show the following pop up
      var errorPopup = $ionicPopup.show({
       scope: $scope,
       title: 'Download Failed',
       templateUrl: 'download-error.html'
      });
      $timeout(function() {
       errorPopup.close();
      }, 2000);
     });
   }

I’ve had a similar issue with uploading recently.
Something I discovered, was that the onProgress event doesn’t get fired when the transfer is complete, so it never reaches 100%.

So what I did was wrap the transfer in a promise, and when resolving that promise, manually set the progress to 100, with a timeout of 1 second to delay the next operation, so you see that it’s finished.

Hope that helps.

Thanks Daveshirman for your reply.

Is it possible to share your code as an example, if that’s not too much?

The if statement prints “Downloaded” if I already download the file and re-run the function again.

It’s angular 2, but the principle is the same, something like this (I’ve taken out all the code that was irrelevant and there are errors here with variable scopes, but the idea is there):

uploadFile(fileUrl: string): Promise<boolean> {
    return new Promise(resolve => {        
        var currentUpload = new Transfer();
        
        currentUpload.onProgress((e) => {
            this._zone.run(() => {
                uploadPercentage = (e.lengthComputable) ?  Math.floor(e.loaded / e.total * 100) : -1;          
            });
        });

        currentUpload.upload(fileUrl, uploadUrl, options).then((data) => {
            resolve(result);
        }).catch(error => {
            currentUpload = null;
            resolve(false);
        });
    },
    error => {
      currentUpload = null;
      resolve(false);
    });    
}

Then in your receiving code:

_someService.uploadFile(selectedFile).then(result => {
    if (result) {
        selectedfileObj.uploadPercentage = 100;
        this.setTimeout(() => { alert('woohooo'; }, 1000);
    }
});

I don’t really understand your code to be honest, cause is Angular 2 as you said. My first sight with Angular 1/Ionic was 1 month ago, so Im still learning Angular 1.

But what I get from your code was the -1 in the total percentage.

So my attempt was:

function(progress) {
        //This function is repeated while the file is downloaded
        
        if ($scope.downloadProgress !=99) {
         $timeout(function() {
          $scope.downloadProgress = Math.round((progress.loaded / progress.total) * 100) -1;
          console.log($scope.downloadProgress);
         }, 500);
        }

        if ($scope.downloadProgress >= 99) {
          console.log("downloaded");
         //In this part I will close the progress popup and show the success popup for a few seconds.
          $scope.downloadProgress = 100;
        }
       }

But I can see the percentage freeze at 99% and the message "downloaded "is never printed.

Ok, forget the -1, that’s just me covering a potential situation where the progress cannot be calculated and that’s my flag value.

The reason you’re only seeing 99% and then a freeze is because when the actual transfer is reaching 100%, the onProgress event doesn’t get called again, it never updates your downloadProgress variable.

So when the transfer is complete, your .then(..)function(result) { promise will resolve.
At that point, manually set the downloadProgress to 100, to show the user it’s done.

I think the .then(…)function(result) resolves at the beginning and then it continues to the function(progress). You can see in the function(result) I have a lot of console.log, I see at the begging of my console all those messages and then the percentage is starting to counting. I guess that’s my issue. It never gets back to the function (progress) neither to function(result).

I’m really sorry if I’m not following you but, I’m trying really hard to follow :slight_smile:

Ok, I suggest looking at this example and defining stuff to happen in your success callback:

https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-file-transfer/#download