0

Hi everyone I am trying to use ajax inside a loop using promise, but my second ajax call inside the loop don't way for the ajax request and continue the execution.

This is my code:

  var general = [];
  var all_info =[];
  var usuario =[];
  var resultPromise = getProjects(); // Promise for a response.
  resultPromise.then(function(all_projects) {
    return $.when.apply($, all_projects.map(function (current_project, index){
      var items = {};
      items.name = current_project.key;
      items.children = [{"total_cpu": current_project.cpuhour_tot, "num_jobs" : current_project.num_jobs }];
      return addUsers(current_project.key)
      .then(function(item_user) {
        info_user = {};
        info_user.name = item_user.key;
        info_user.children = [{"total_cpu" : item_user.cpuhour_tot, "num_jobs": item_user.num_jobs }];
        all_info.push(info_user);
      });
      items.children.push(all_info);
      general.push(items)
    }));
  })
  .then(function() {
    console.log("complete", general);
  })
  .fail(function(jqxhr, textStatus, errorThrown) {
    console.log(errorThrown);
  })

when I return from this line return addUsers... I need to include the all_info values to items and before to execute other loop to all_projects I have to do that general.push(items)

but it is impossible to access to items.

What I am missing?

Thanks in advance!

Stone
  • 749
  • 1
  • 11
  • 30
  • instead of foreach do a while loop and increment a counter after promise is done . get it ? –  Dec 16 '16 at 18:23
  • http://stackoverflow.com/questions/18424712/how-to-loop-through-ajax-requests-inside-a-jquery-when-then-statment – bassxzero Dec 16 '16 at 18:25
  • Why do you the same identifier within `.forEach()` at `var resultPromise = addUsers(current_project.key);`? – guest271314 Dec 16 '16 at 18:25
  • Promises are asynchronous, your code iterates over the results, assigns a callback to the request then moves on. It will log "last" then when the requests resolve the callback will be triggered and "first" will be logged. – Matt Dec 16 '16 at 18:29

2 Answers2

1

Substitute .map() for .forEach() use $.when(), Function.prototype.apply(). usuario is an array; .push() value to the array.

resultPromise.then(function(all_projects) {
  return $.when.apply($, all_projects.map(function (current_project, index){
    var items = {};
    items.name = current_project.key;
    items.children = [{"total_cpu": current_project.cpuhour_tot, "num_jobs" : current_project.num_jobs }];
    return addUsers(current_project.key)
    .then(function(value) {
      console.log(value)
      usuario.push(value);
      // use value here before continues;
      // do stuff with `value` or `usuario` here
    });
  }));
})
.then(function() {
  console.log("complete", usuario)
})
.fail(function(jqxhr, textStatus, errorThrown) {
  console.log(errorThrown)
})
guest271314
  • 1
  • 15
  • 104
  • 177
  • Hi @guest271314 Thanks for the request I use your code but after finish this return I have to use this value in items, but I don't find the way to modified items `items.children.push(all_info);` – Stone Dec 16 '16 at 19:52
  • 1
    Both `items.children.push(all_info);general.push(items)` should be within function at `.then()` chained to `addUsers()` call. Since `items` is a local variable within `.map()` `items` is not defined outside of the promise chain, though you `.push()` `items` to `general` array, so you should be able to access those elements at `.then()` chained to `resultPromise`; e.g.,`usuario.push(value);items.children.push(all_info);general.push(items)`, `console.log("complete", usuario, general)` – guest271314 Dec 16 '16 at 20:01
0

Reading about the asynchronous and single threaded nature of javascript would help you understand what happens here.

Essentially the following instruction:

resultPromise.then(function(value) {
  usuario = value;
  // use value here before continues;
  console.log("first");
});

Is asking "Execute the callback function at some point in the future when the promise is resolved and execution stack is cleared". The callback function doesn't run in place, and actually won't run until after the current execution thread completes.

IAmDranged
  • 2,890
  • 1
  • 12
  • 6