0

I'm trying to use a .when with an .each to loop through some elements and .then do something with the results. But I'm not sure how to store the results from the .when to use in the .then.

for example

var widget_data = [];

$.when(
    $.each(widget_ids, function(index, widget_id){
        $.get('/widget/' + widget_id, function(data){
            widget_data.push(data);
        });
    })
)
    .then(function(){
        console.log(widget_data);
    });

The widget_data array is empty after running.

waspinator
  • 6,464
  • 11
  • 52
  • 78

2 Answers2

1

You need to use .map() not .each()

var widget_data = [];
$.when.apply($,
    $.map(widget_ids, function(widget_id, index) {
      return $.get('/widget/' + widget_id, function(data) {
        widget_data.push(data);
      });
    })
  )
  .then(function() {
    console.log(widget_data);
  });

When you use .each(), it returns the array which was passed to it, since it is not an promise object, $.when() will consider it as resolved and will call the then handler without waiting for the ajax requests to complete.

You can use $.map() to create an array of promise objects from the source array, which can be passed to $.when() as above, in that case the then handler will be called only after all the requests are completed - but note that the order of values in the result array may not match the order of items in the source array.

Arun P Johny
  • 384,651
  • 66
  • 527
  • 531
1

One issue is that when needs to get deferered as a parameter(s), and $.each does not return one.

var promises = [];
$.each(widget_ids, function(index, widget_id){
    promises.push( $.get('/widget/' + widget_id, function(data){
        widget_data.push(data);
    }) );
});

$.when.apply($, promises);
 .then(function(){
    console.log(widget_data);
});
Gabriele Petrioli
  • 191,379
  • 34
  • 261
  • 317