2

I'm using a grid widget to display a bunch of data. Because of the way the grid works, I need to run an ajax query on each of the rows in the table after it has loaded. (I tried to figure out a better way, there isn't one.) I'm running the queries at the correct time, that's not an issue, but my page is returning strange results.

I have to go through each row of the table for other functions as well, so I'm running the ajax calls inside the for loop that everything else (synchronous) runs inside. The ajax calls are both sending and receiving back the correct data, but it's not being applied to the grid. I have three possible return values: read applies the read-row class, alert applies the alert-row class, and none is a dummy return that does nothing other than indicate success. If anything in the row returns read, however, that class is being applied to the last row of the grid instead of the one that was originally referenced in the request.

What am I doing wrong? How would I rewrite this to correctly apply the given class based on the ajax response? The declarations of the row information, data, and the ajax call itself are all correct. The correct information is being sent in the call, and the correct information is being received back.

Here's my current code. I tried putting the success function in as a done block appended to the ajax call, but that causes the same problem.

// this is the correct initialization
var gridData = grid.dataSource.view();
for (var i = 0; i < gridData.length; i++) {

    // these are also correct. I can step through with the debugger and 
    // currentRow is properly set
    var currentUid = gridData[i].uid;
    var currentRow = grid.table.find("tr[data-uid='" + currentUid + "']");

    // the grid caches its row information when refreshed, so this is
    // necessary to "reset" the row
    $(currentRow).removeClass("read-row");
    $(currentRow).removeClass("alert-row");

    // other synchronous stuff, only manipulates individual cell data

    $.ajax({
        cache: false,
        type: "GET",
        url: "/correct/url",
        data: { "pId": gridData[i].Id },
        dataType: "text",
        success: (function(res) {
            if (res === "read") {
                $(currentRow).addClass("read-row");
            } else if (res === "alert") {
                $(currentRow).addClass("alert-row");
            }
        }),
        error: (function() {
            alert("errormsg");
        })
    });

    // more synchronous stuff, only manipulates individual cell data
}
vaindil
  • 7,536
  • 21
  • 68
  • 127
  • use forEach to iterate over an array. Doing so will also help the ajax issue. – Kevin B Feb 04 '16 at 21:04
  • by the time `success` is called, `currentRow` will be the last one for every success callback .. use a closure – Jaromanda X Feb 04 '16 at 21:05
  • I suspect that currentRow referenced in the success portion of your ajax call isn't the came currentRow that you initiated the ajax call for. you need a way to tie the call itself to the row you're calling it for. It's been a while but I think there is a way to pass extra data to an ajax call that is available in the result methods. That 'extra data' you need to pass is currentRow. – n8wrl Feb 04 '16 at 21:06
  • @JaromandaX well, he is using a closure, that's part of the problem. – Kevin B Feb 04 '16 at 21:06
  • @Kevin - not sure about that – Jaromanda X Feb 04 '16 at 21:07
  • the success callback is currently closing over the `currentRow` variable, making it a closure. – Kevin B Feb 04 '16 at 21:09
  • @KevinB `forEach` is all I needed, I didn't know about that. Thank you! – vaindil Feb 04 '16 at 21:15
  • I just tested this on jsfiddle, the current row ends up being the last one before the ajax call succeeds. So in order to fix this, wrap the ajax call with: `(function(currentRow){ //ajax call// })(currentRow);` – Micaiah Wallace Feb 04 '16 at 21:16

0 Answers0