function within loop gets called after loop has finished
-
21-12-2019 - |
Question
function initGrids() {
for (var i = 0; i < grids.length; i++) {
$('#' + grids[i].gridName).kendoGrid({
columns: [{
width: 50, "template": "<input type=\"checkbox\" />"
},
{
field: "Name",
title: "Name"
}],
dataBound: function () {
noRecords(grids[i].gridName);
}
}).css('width', '100%');
}
}
I have this function in which I initialize multiple kendo ui grids. The grid has functions such as databound and transport.read which can be called at any time.
This means that functions like dataBound are called after the for loop is done. This also means the incremental variable var i; will be at grids.length + 1, so when the dataBound function is called, which contains this piece of code noRecords(grids[i].gridName)
, the grids[i] will be at the wrong index!
one way to solve is manually defining the grids one by one, but I have three grids which have the exact same columns etc. But then the code will look bad, since I'm repeating things.
How can I solve this?
Solution
Use a separate function or use a closure
Closure
for (var i = 0; i < grids.length; i++) {
(function(index){
$('#' + grids[index].gridName).kendoGrid({
columns: [{
width: 50, "template": "<input type=\"checkbox\" />"
},
{
field: "Name",
title: "Name"
}],
dataBound: function () {
noRecords(grids[index].gridName);
}
}).css('width', '100%');
})(i);
}
Or function
function initGrid(grid){
$('#' + grid.gridName).kendoGrid({
columns: [{
width: 50, "template": "<input type=\"checkbox\" />"
},
{
field: "Name",
title: "Name"
}],
dataBound: function () {
noRecords(grid.gridName);
}
}).css('width', '100%');
}
for (var i = 0; i < grids.length; i++) {
initGrid(grids[i]);
}
OTHER TIPS
You have to use a closure here to capture i with its loop specific value
// ...
dataBound: (function (index) {
return function(){
noRecords(grids[index].gridName);
}
})(i)
// ...