1

I want to popup/display a dialog. It has two tabs and in each of these tabs there is a table (lets say table1 and table2).

Both of these tables contain data those are populated by a rest/ajax service (lets say service1 and service2).

When each of these rest services completes, the table component is populated with the data.

On top of this, the dialog has a spinner widget activated when the dialog first pops up.

The spinner widget is deactivated when BOTH of the rest services have completed.

For table1 I have code that looks a bit like this :

this.updateTable1 = function (dialog)
{
    dialog.setSpinner(true)

    var call = {}
    call.url = 'service1';
    call.xmlHttpReq = $.ajax({
        url: url,
        dataType: 'json',
        async: true,
        type: 'GET'
    }).always(
       function (processedDataOrXHRWrapper, textStatus, xhrWrapperOrErrorThrown) 
       {
         dialog.table1.loadData(processedDataOrXHRWrapper);
         dialog.setSpinner(false)
       });
};

For table2 the code is pretty much the same.

Which means that it also has dialog.setLoading(false). This means that whichever process finishes first, the spinner is deactivated, which is incorrect behaviour.

Somehow the two ajax calls need to know about each other, but I don't like that idea :(. Should I have some kind of third object that stores state of which processes have finished?

I tried using ajax calls in sync mode, but that just blocks the display thread in the browser.

Reporter
  • 3,897
  • 5
  • 33
  • 47
Oliver Watkins
  • 12,575
  • 33
  • 119
  • 225
  • Just a suggestion can you load both the tables before opening dialog, however show spinner. Once both the tables 1 and 2 are binded with data, then load the main dialog and hide the spinner. If any of the two dialog fails stop the spinner. Basically load first table on success of it load second table and on sucess of it load dialog. any where failed hide spinner and exit. – Girish Sakhare Sep 26 '14 at 14:11

1 Answers1

1

You can use Deferred promises to implement this.

var updateTable1 = function (dialog)
{
    return $.ajax({
        url: url,
        dataType: 'json',
        async: true,
        type: 'GET'
    }).always(
       function (processedDataOrXHRWrapper, textStatus, xhrWrapperOrErrorThrown) 
       {
         dialog.table1.loadData(processedDataOrXHRWrapper);)
       });
};
// and same for updateTable2 

dialog.setSpinner(true);
$.when(updateTable1(dialog), updateTable2(dialog)).always(function() {
               dialog.setSpinner(false);
});

Only issue with the above is that, if the ajax call in updateTable1 or updateTable2 fails, the always function is immediately called. If you don't want this - see the $.whenall function in the answer to this question: jquery deferred - "always" called at the first reject

Community
  • 1
  • 1
mccannf
  • 16,619
  • 3
  • 51
  • 63