-1

I'm having some trouble with jQuery deferreds. Here's my code:

function makeAjaxCalls(purge){
  var deferreds = [];
  // delete the documents
  _.each(purge, function(element, index, list){
    console.log('purging '+element.model+' id='+element.id);
    deferreds.push(
      $.ajax({
        type: 'DELETE',
        url: '/API/admin/purge/'+element.model+'/'+element.id
      })
    );
  });
  console.log('returning array with '+deferreds.length+' deferreds');
  return deferreds;
};

function purgeDeletedDocs(){
  console.log('purging...');
  var purge = [];
  _.each(arrayOfIDs, function(element, index, list){
    purge.push({'model': arrayOfModels.get(element).get('modelName'), 'id': element});
  }); // [{model: 'modelName', id: 'id'}...]
  // when *all* the AJAX calls are resolved run this code
  $.when.apply(this, deferreds).done(function(){
    console.log('done');
  });
  var deferreds = makeAjaxCalls(purge);
};

purgeDeletedDocs()

As you can see I'm using $.when.apply as I'm returning an array of deferreds from the makeAjaxCalls() function.

Here's what I'm getting in the console:

purging...
done
purging User id=5564e0f647f054512a9d64c9
purging Client id=557079a04407058a49fd2f3d
returning array with 2 deferreds

Now that's odd. I'm seeing the done before the AJAX calls have been even made, let alone resolved. I'm passing this into the apply() but using $ etc. makes no difference - and reading the docs for apply() the first parameter just sets the this for the code so that's the expected behaviour.

The server is correctly getting the API calls made so the AJAX calls are being made, it's just that the multiple deferreds seem to resolve and trigger the .done() before they're even made.

Any ideas as to what am I doing wrong?

David Williamson
  • 387
  • 1
  • 5
  • 18
  • You appear to be calling `makeAjaxCalls(purge)` ***after*** you call `$.when.apply($, deferreds)`? – Rory McCrossan Jun 10 '15 at 16:03
  • your definition of deferreds come after the when this means that the promises resolved immediately - and that means that it is called before the actual request is made fro akeAjaxCalls(purge); – Dan Kuida Jun 10 '15 at 16:03

1 Answers1

2
// when *all* the AJAX calls are resolved run this code
$.when.apply(this, deferreds).done(function(){
    console.log('done');
});
var deferreds = makeAjaxCalls(purge);

As you can see I'm using $.when.apply as I'm returning an array of deferreds from the makeAjaxCalls() function.

Well but you're not passing them into the $.when function. Instead, you are passing undefined to $.when, even before making that call to makeAjaxCalls()!

Reorder your statements to

var deferreds = makeAjaxCalls(purge);
$.when.apply(this, deferreds).done(function(){
    console.log('done');
});
Bergi
  • 630,263
  • 148
  • 957
  • 1,375