1

I am trying to implement Uploadcare for multi-image upload, but confused about the code structure. Below code works, but it has two .fail blocks and two .done blocks. Additionally, adding the images to the front-end using $.each() should be done after the group has been saved on the server, while this code executes both simultaneously.

How can this code be improved?

$('button').on('click', function() {

    var myDialog = uploadcare.openDialog(null, {
        imagesOnly: true, multiple: true, multipleMin: 1, multipleMax: 7
    });

    myDialog.fail(function(error, fileInfo) {
        alert('Upload fialed');
    });

    myDialog.done(

        groupInstance => {  
            var groupPromise = groupInstance.promise();
            var arrayOfFiles = groupInstance.files();

            groupPromise.done(function(fileGroupInfo) {
                /* Save group to server using Ajax */
                uploadGroup(fileGroupInfo.uuid);
            });

            groupPromise.fail(function(error, fileGroupInfo) {
                alert('Upload failed');
            });

            $.each(arrayOfFiles, function(i, file) {
                file.done(function(fileInfo) {
                    /* Add image to front-end */
                });
            });
        });

       return false;
    });

And the AJAX function:

uploadGroup = function(imgurl) {        
    $.post('index.php',
    {string:imgurl},
    function(data) {
        if(data.status=='success') {
            alert('success');
        }
        else {
            alert('error');
        }
    },'json');
};

Also confused about the groupInstance => notation.

bart
  • 14,958
  • 21
  • 75
  • 105
  • 1
    `=> notation.` [arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) – Jaromanda X Oct 03 '18 at 00:21
  • 1
    What you haven't shown is the Ajax used to `Save group to server using Ajax` - these too will likely return jQuery promises (if you use $.ajax or one if it's shortcut cousins) and it's these promises you'll want to wait for before executing the $.each – Jaromanda X Oct 03 '18 at 00:33
  • @JaromandaX Good point, added it! – bart Oct 03 '18 at 00:41
  • does uploadGroup upload all the selected files? – Jaromanda X Oct 03 '18 at 00:42
  • @JaromandaX No, that's not necessary with UploadCare. Using the group's :uuid from Uploadcare, the images can be retrieved from the group server side using REST API. – bart Oct 03 '18 at 00:43
  • Oh, right ... each file upload triggers each `file.done`? – Jaromanda X Oct 03 '18 at 00:44
  • @JaromandaX Exactly, when an image is done uploading, it's added to the front-end (but not saved to the server, because that's being taken care of by the REST API). – bart Oct 03 '18 at 00:47

1 Answers1

3

It seems arrayOfFiles is an array of promises?

So, you wait for all of them to complete using $.when

and since you're already using modern javascript, going to add another "oddity" you may not be familiar with ..., but it makes things easier

I may have misunderstood what you wanted to wait for

   groupInstance => {  
        var groupPromise = groupInstance.promise();
        var arrayOfFiles = groupInstance.files();

        groupPromise.done(function(fileGroupInfo) {
            /* Save group to server using Ajax */
            uploadGroup(fileGroupInfo.uuid);

            // move the .each code here
            $.each(arrayOfFiles, function(i, file) {
                file.done(function(fileInfo) {
                    /* Add image to front-end */
                });
            });

            /* Probably not what you wanted
            $.when(...arrayOfFiles).then((...fileInfos) => {
                $.each(fileInfos, function(i, fileInfo) {
                    // Add image to front-end
                });
            });
            // the above 5 lines in old school JS
            $.when.apply(null, arrayOfFiles).then(function() {
                var fileInfos = [].slice.call(arguments);
                $.each(fileInfos, function(i, fileInfo) {
                    // Add image to front-end
                });
            });
            */
        });

        groupPromise.fail(function(error, fileGroupInfo) {
            alert('Upload failed');
        });
    }

...arayOfFiles ... ... is spread syntax ... so

$.when(...arrayOfFiles)

is like

$.when.apply(null, arrayOfFiles)

and function(...fileInfos) is Rest Syntax

function(...fileInfos) {

is equivalent to

function() {
    fileInfos = [].slice.call(arguments);
}

is like

Jaromanda X
  • 53,868
  • 5
  • 73
  • 87
  • Cool, thanks, I think the modernism of this JavaScript is confusing me. Where do I place the $.when? – bart Oct 03 '18 at 01:02
  • 1
    oh, sorry, that's where you currently have `$.each(arrayOfFiles` - let me make it clearer - I'll write it old school as well ... hang on – Jaromanda X Oct 03 '18 at 01:03
  • Do you agree that var arrayOfFiles is a confusing name (because it's not an array of files) and should be var filePromises instead? – bart Oct 03 '18 at 01:14
  • 1
    if that's what it is - which I assume is correct from your code - yes, but it's actually not Promises, it's some sort of jquery XHR object that includes .fail/.done - which work like promises :p – Jaromanda X Oct 03 '18 at 01:24
  • Unfortunately, when testing the code, $.when.apply still runs before groupPromise.done :/ – bart Oct 03 '18 at 01:41
  • 1
    d'oh, I forgot that bit :P – Jaromanda X Oct 03 '18 at 02:01
  • 1
    pretty sure you actually didn't want or need that $.when stuff @bart – Jaromanda X Oct 03 '18 at 02:04