Sebastian
Sebastian

Reputation: 4811

AJAX requests inside a loop

I am trying to call multiple ajax requests inside a loop to load multiple dropdown lists. I tried the sequential way and i can see that the last item in loop only is getting filled with values

 var targetcontrols = [];
        var targetcontrols_array = targetControl.split(',');
        var targetsourcecontrols = [];
        var targetsource_array = targetSource.split(',');
        for(i=0; i < targetcontrols_array.length; i++)
        {
            var control_name=targetcontrols_array[i];
            var source=targetsource_array[i];
            $.ajax({
                url: action_url,
                type: 'POST',
                traditional: true,
                async: false,
                data: JSON.stringify( { allselected: allselected_flag, selectedIds: selectedvalues,targetControl:control_name,  targetSource: source, dependency: dependencyOptions } ),
                contentType: "application/json; charset=utf-8",
                dataType: 'json',
                success: function (response) {
                    //To clear existing items
                    var target= $("#"+response.targetControl);
                    target.multiselect('dataprovider', []);
                    var dropdown2OptionList = [];
                    for (i = 0; i < response.values.length; i++) {
                        dropdown2OptionList.push({
                            'label': response.values[i].text,
                            'value': response.values[i].value
                        })
                    }
                    console.log("--control"+control_name);
                    //re initialize the search plugin
                    target.multiselect('dataprovider', dropdown2OptionList);
                    target.multiselect('rebuild');
                }
            });

How can i ensure the first item in the loop also is getting filled with response values

Upvotes: 0

Views: 73

Answers (3)

tam.dangc
tam.dangc

Reputation: 2032

These 2 declarations:

var control_name = targetcontrols_array[i];
var source = targetsource_array[i];  

maybe cause the problem. Because var has function scope and for loop is a block scope, so when you use the loop, these control_name and source variables got replaced from the next one, before used in ajax request. That's why you always get the last. You should change var into const or let which support block scope

const control_name = targetcontrols_array[i];
const source = targetsource_array[i];

Upvotes: 1

tam.dangc
tam.dangc

Reputation: 2032

You can try map to produce an array of Promise. After that use Promise.all() to execute this promises array.

var targetcontrols = [];
var targetcontrols_array = targetControl.split(',');
var targetsourcecontrols = [];
var targetsource_array = targetSource.split(',');
const arrOfPromises = targetcontrols_array.map(function(item, index) {
  const control_name = item;
  const source = targetsource_array[index];
  return new Promise((resolve) => {
    $.ajax({
      url: action_url,
      type: 'POST',
      traditional: true,
      async: false,
      data: JSON.stringify( { allselected: allselected_flag, selectedIds: selectedvalues,targetControl:control_name,  targetSource: source, dependency: dependencyOptions } ),
      contentType: "application/json; charset=utf-8",
      dataType: 'json',
      success: function (response) {
        //To clear existing items
        var target= $("#"+response.targetControl);
        target.multiselect('dataprovider', []);
        var dropdown2OptionList = [];
        for (i = 0; i < response.values.length; i++) {
          dropdown2OptionList.push({
            'label': response.values[i].text,
            'value': response.values[i].value
          })
        }
        console.log("--control"+control_name);
        //re initialize the search plugin
        target.multiselect('dataprovider', dropdown2OptionList);
        target.multiselect('rebuild');
        resolve(`done for url ${control_name}`) // Show log for checking process
      }
  })
})
  
Promise.all(arrOfPromises)

Upvotes: 1

Barr J
Barr J

Reputation: 10919

First of all if you use jquery, utilize it's full potential, instead of for loops, use $.each:

var targetcontrols = [];
        var targetcontrols_array = targetControl.split(',');
        var targetsourcecontrols = [];
        var targetsource_array = targetSource.split(',');
        $.each(targetcontrols_array, function(i, item)
        {
            var control_name=targetcontrols_array[i];
            var source=targetsource_array[i];
            $.ajax({
                url: action_url,
                type: 'POST',
                traditional: true,
                async: false,
                data: JSON.stringify( { allselected: allselected_flag, selectedIds: selectedvalues,targetControl:control_name,  targetSource: source, dependency: dependencyOptions } ),
                contentType: "application/json; charset=utf-8",
                dataType: 'json',
                success: function (response) {
                    //To clear existing items
                    var target= $("#"+response.targetControl);
                    target.multiselect('dataprovider', []);
                    var dropdown2OptionList = [];
                    $.each(response.values, function(v, vItems) {
                        dropdown2OptionList.push({
                            'label': response.values[v].text,
                            'value': response.values[v].value
                        })
                    });
                    console.log("--control"+control_name);
                    //re initialize the search plugin
                    target.multiselect('dataprovider', dropdown2OptionList);
                    target.multiselect('rebuild');
                }
            });
        });

Upvotes: 0

Related Questions