1

I am sending formdata to PHP using ajax.upload for upload file to Google cloud storage

Javascript:

 var ajax = new XMLHttpRequest();

//PROGRESS HANDLER
ajax.upload.addEventListener("progress", function(event) {
  var percent = ((event.loaded / event.total) * 100);
  console.log(Math.round(percent) + "% uploading... please wait");
}, false);

//COMPLETE HANDLER
ajax.addEventListener("load", function(event) {
  console.log(event.target.responseText);  
}, false);

//ERROR HANDLER
ajax.addEventListener("error", function(event) {
  console.log("Upload Failed");  
}, false);

//ABORT HANDLER
ajax.addEventListener("abort", function(event) {
  console.log("Upload Aborted");  
}, false);

ajax.open("POST", "api/storage.php");
ajax.send(formdata);

PHP:

    $_SESSION['storedBytes'] = 0;
    $_SESSION['fileSize'] = $file["size"];

    $uploader = $bucket->getResumableUploader(
      fopen($fileTmpLoc, 'r'),
      [
              'predefinedAcl' => 'publicRead',
              'name' => $_POST['uniqueName'],
              'resumable' => true,
              'chunkSize' => 262144,
              'uploadProgressCallback' => 'uploadProgress'
          ]
    );

    try {
        $object = $uploader->upload();
    } catch (GoogleException $ex) {
        $resumeUri = $uploader->getResumeUri();
        $object = $uploader->resume($resumeUri);
    }

function uploadProgress($storedBytes)
{
    if (isset($_SESSION['storedBytes'])) {
        $_SESSION['storedBytes'] += $storedBytes;
    } else {
        $_SESSION['storedBytes'] = $storedBytes;
    }
    $storedBytes = $_SESSION['storedBytes'];
    $totalSize = $_SESSION['fileSize'];
    $_SESSION['progress'] = ($storedBytes*100)/$totalSize;
    echo "Progress ".$_SESSION['progress'];
}

And i receive the correct progress value in uploadProgress function but how to send this value to ajax request response asynchronously or how to show progress in this situation.

Sabish.M
  • 2,022
  • 16
  • 34
  • Possible duplicate of [PHP Ajax Upload Progress Bar](https://stackoverflow.com/q/9878161/1255289) – miken32 Sep 26 '18 at 19:02
  • I would consider using Promises and Deferreds in your ajax calls. I will try to provide an example as soon as possible. – turtlechief Sep 26 '18 at 19:16

1 Answers1

0

I would use promises in your javascript ajax calls. A jQuery example would be something like this:

// gets the state of the upload from the PHP server.
var getProgress = function(phpUrlForProgress){
    return $.ajax({
        url: phpUrlForProgress,
        type: 'get'
    });
};

var keepCheckingProgress = function(phpUrlForProgress){
    var deferred   = $.Deferred();
    var intervalID = setInterval(function(){
        getProgress(phpUrlForProgress).done(function(response){
            console.log(response); // see what the response looks like.

            // you might need to parse the response into JSON before your if() statement.
            if(response.percentComplete === 100) {// You are done with the upload
                clearInterval(intervalID); // stops the setInterval loop;
                deferred.resolve(response);
            } else {
                // some code to display a progress bar or whatever.
            }
        });
    }, 3000);// setInterval function repeats every 3 seconds until cleared.

    return deferred.promise();     
};

// initiates the upload.
$.ajax({
    url: phpUrlForUpload,
    type: 'post'
    data: formdata
});

// now start checking for upload progress.
var finished = keepCheckingProgress();

$.when(finished).then(function(){
    // do something now that the upload is 100% done
}); 

Please note that I have not had a chance to test this code for bugs or errors, it is just to give you an idea.

Basically Promises are a way to bring some order of operations to Javascript, which is asynchronous. It is a way of saying, when this task finishes, do some other task.

jQuery I believe uses a slightly different Promise implementation than other promise libraries. A general primer on promises can be found here.

turtlechief
  • 100
  • 1
  • 7
  • not success. Because keepCheckingProgress is called after upload is completed. It's not asynchronous. – Sabish.M Sep 27 '18 at 02:41
  • ok, I will fixed it. By moving the `keepCheckingProgress` call outside of the `.done()` part of the ajax call that initiates the upload, it will now fire immediatedly after the upload, without waiting for the ajax call to get a response. – turtlechief Sep 27 '18 at 19:35