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.

5
  • So what's happening with the above approach? Commented Jan 25, 2016 at 3:55
  • I see the XHR requests happen after the console.log, and widget_data is empty Commented Jan 25, 2016 at 3:57
  • Keep a console.log(data) inside $.get and see whether you are getting data there Commented Jan 25, 2016 at 4:00
  • console.log(data) inside the .when works and shows the resulting data. it seems .then is run right away without waiting for the .when to finish. Commented Jan 25, 2016 at 4:03
  • try .done instead of .then Commented Jan 25, 2016 at 4:06

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! that worked great. Any thoughts on Gaby's solution? seems to produce the same results.
@waspinator thet are the same, only the apis used to create the promise array is different
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);
});

1 Comment

Thanks! both yours and Arun's solutions work. Any thoughts on his?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.