0

I am new to JavaScript. I am creating one table dynamically; I am facing a problem with the order of execution. I know JavaScript code won't execute sequentially, but what will be the work around?

First I will brief what I am trying to do.

1) loadList () -> I will call this method on click of load data button here I will fire AJAX request to get data

2) using the result of above AJAX request, I am trying to create table rows

3) few table rows td having combo box, whose value to be filled using another AJAX call, passing the rowObject value

Below is my code:

var loadList = function(){

//ajax call
$.ajax({
    url:"tworows.json",
    type: "GET",
    dataType : "json"
})
.done(function(data, textStatus, jqXHR){
    generateTable(data);
});
};


function generateTable(data){

$("#gridTable").empty();

//create table header
var headertr = $("<tr><th>col1 </th><th>col 2</th><th>col 3</th><th>col 4</th><th>col 5</th><th>col 6</th><th>col 7</th></tr>");

//get table id from jquery
var tableelement = $("#gridTable");

//add header row to table
tableelement.append(headertr);


for(var i=0; i< data.links.id.length; i++){
        tableelement.append(createRow(data.links.id[i]));
}       

}

function createRow(rowObject){

//used to create combo box 1 based row 1 value
var combo1 = createCombo1(rowObject);

//used to create combo box 2 based row 1 value
var combo2 = createCombo2(rowObject);


var trElement = "<tr>"+
        "<td><input type='text' name='col1name' value='"+rowObject.Number+"' onblur='handleInput(this)'/></td>"+
        "<td><input type='text' name='col3name' value='"+rowObject.name+"'/></td>"+
        "<td><input type='text' name='col3name' value='"+rowObject.quantity+"'/></td>"+
        "<td>"+combo1+"</td>"+
        "<td>"+combo2+"</td>"+
        "<td><button>Del</button></td>" +
        "<td><button>Add</button></td></tr>";

return trElement;
}

function createCombo1(rowObject){

var comboList = [];
    //call ajax to get combo value
    $.ajax({
        url:"combo1data.json",
        type: "GET",
        dataType : "json",
        async : false
    })
    .done(function(data, textStatus, jqXHR){
        comboList = data.links.id;
    });     

    var cmb1 = "<select  name='cmb1' onchange='handlecmb1Change(this)'>";
    for(var i=0;i < comboList.length; i++){
    cmb1 +="<option value='"+comboList[i].id+"'>"+comboList[i].name+"</option>";
    }

    cmb1 += "</select>";

    return cmb1;
}

function createCombo2(rowObject){
var comboList = [];
//call ajax to get combo value
$.ajax({
    url:"combo2data.json",
    type: "GET",
    dataType : "json",
    async : false
})
.done(function(data, textStatus, jqXHR){
    comboList = data.links.id;
});
var cmb2 = "<select onchange='handlecmb2Change(this)'>";

for(var i=0;i < comboList.length; i++){
    cmb2 +="<option value='"+comboList[i].id+"'>"+comboList[i].name+" </option>";
    }

cmb2 += "</select>";
return cmb2;
}

Here row is creating first, after that control is going to createCombo methods. Because of this I am not getting combo boxes in td.

I want to create combobox based on first result of AJAX call; using the first result I need to call other 2 AJAX calls and populate them in the td combobox.

user3231742
  • 77
  • 1
  • 2
  • 10

2 Answers2

2

Please use below code block, this might be solve your problem. Your requirement need synchronous execution of methods, for this you need to use callback structure. below is the code :

var loadList = function(){

//ajax call
$.ajax({
    url:"tworows.json",
    type: "GET",
    dataType : "json"
})
.done(function(data, textStatus, jqXHR){
    generateTable(data);
});
};


function generateTable(data){

$("#gridTable").empty();

//create table header
var headertr = $("<tr><th>col1 </th><th>col 2</th><th>col 3</th><th>col 4</th><th>col 5</th><th>col 6</th><th>col 7</th></tr>");

//get table id from jquery
var tableelement = $("#gridTable");

//add header row to table
tableelement.append(headertr);


for(var i=0; i< data.links.id.length; i++){
        tableelement.append(createRow(data.links.id[i]));
}       

}

function createRow(rowObject){

var trElement = "<tr>";

//used to create combo box 1 based row 1 value
var combo1 = createCombo1(rowObject,function(response){
    //used to create combo box 2 based row 1 value
    var combo2 = createCombo2(rowObject,function(result){
        trElement+= "<td><input type='text' name='col1name' value='"+rowObject.Number+"' onblur='handleInput(this)'/></td>";
        trElement+="<td><input type='text' name='col3name' value='"+rowObject.name+"'/></td>";
        trElement+="<td><input type='text' name='col3name' value='"+rowObject.quantity+"'/></td>";
        trElement+="<td>"+response+"</td>";
        trElement+="<td>"+result+"</td>";
        trElement+="<td><button>Del</button></td>";
        trElement+="<td><button>Add</button></td></tr>";
    });
});

return trElement;
}

function createCombo1(rowObject,callback){

var comboList = [];
    //call ajax to get combo value
    $.ajax({
        url:"combo1data.json",
        type: "GET",
        dataType : "json"
    })
    .done(function(data, textStatus, jqXHR){
        comboList = data.links.id;
        var cmb1 = "<select  name='cmb1' onchange='handlecmb1Change(this)'>";
        for(var i=0;i < comboList.length; i++){
        cmb1 +="<option value='"+comboList.id+"'>"+comboList.val+"</option>";
        }

        cmb1 += "</select>";
        return callback(cmb1);
    });     
}

function createCombo2(rowObject,callback){

var comboList = [];
    //call ajax to get combo value
    $.ajax({
        url:"combo2data.json",
        type: "GET",
        dataType : "json"
    })
    .done(function(data, textStatus, jqXHR){
        comboList = data.links.id;


        var cmb2 = "<select  name='cmb1' onchange='handlecmb1Change(this)'>";
        for(var i=0;i < comboList.length; i++){
        cmb1 +="<option value='"+comboList.id+"'>"+comboList.val+"</option>";
        }

        cmb2 += "</select>";
        return callback(cmb2);
    });     

}

thanks

Arpit Jain
  • 455
  • 3
  • 8
  • 1
    Thanks Arpit, as i am new to JS let me know which is the best practise? making async false or using callbacks in these kind of scenario ? – user3231742 Jun 06 '14 at 05:25
  • The best practice is using callbacks as i used in above example. The reason is that using callback methodology, the current execution of the process is on hold until the callback provoke it again. And in most of the cases when async AJAX calls needed, this terminology gives most accurate behavior with respect to do async False in AJAX call. One more reason to do that is, when we want to get an output from a sequential AJAX call, it gives you best result. If my solution gets you to your result, please marked it as useful. Thanks. – Arpit Jain Jun 06 '14 at 05:36
  • Arpit, your suggestion works when async is false. if async is true row is not creating. even if we use callback we need to make async false? – user3231742 Jun 06 '14 at 06:11
0

There are several problems that need to be addressed.

First, the return value from an ajax callback won't go anywhere.

This line

var combo1 = createCombo1(rowObject);

Will set combo1 to undefined every single time. Because createCombo1() doesn't return anything. The anonymous function inside of createCombo1() is what returns the value your looking for, but in this case you can't use that return value.

What I recommend for createCombo1() and createCombo2() is to save the return value to a global variable or maybe even an array, so you can access them when they are done.

Which brings me to the next problem...how do you know when they are done?

jQuery has something called a deferred object. Which allows you to chain multiple callbacks to one function. There is a similar SO question that addresses how to use this using When().

Here is the question

There is still a lot to do on your end, but hopefully this will point you in the right direction.

Community
  • 1
  • 1
Smeegs
  • 9,151
  • 5
  • 42
  • 78
  • Thanks Smeegs, ya i removed few things when posting here, i corrected those, now i can able to generate table. what I got is javascript go line by line, if ajax call is there means order of exe changes. if u make async false means flow goes sequentially. I hope i got it right? – user3231742 Jun 05 '14 at 12:34