Cloudrocket Cloudrocket - 6 months ago 13
Javascript Question

Nested for loop incrementation producing inconsistent result

I'm trying to use the variable of the current iteration of the loop in the nested loop.

However when I execute the following code the loop incorrectly starts at f = 6, and then it correctly iterates over the nested loop.

I've removed all the other code and then it works normally. However I have no clue what could possibly be interfering with the loop. There probably is a reason for it and I wish you guys could help me figure this out - and probably learn something more about why this behaviour occurs the way it does.

for (var f = 0; f < 6; f++) {

var JSONURL = "http://blabla.com/json";

$.ajax( JSONURL, {
dataType: "json"
})
.done(function(json) {

for (var i = 0; i < json.timeslots.length; i++) {

var StartHour = json.timeslots[i].begintijd.split(":")[0];
var StartMinute = json.timeslots[i].begintijd.split(":")[1];
var EndHour = json.timeslots[i].eindtijd.split(":")[0];
var EndMinute = json.timeslots[i].eindtijd.split(":")[1];

//Calculate top distance of block in pixels
if (StartHour < 20) {
var TopDistance = ((parseInt(StartHour) - 9) * 240) + (parseInt(StartMinute) * 4);

}

//Calculate height of block in pixels
var BlockHeight = ((((parseInt(EndHour) * 60) + (parseInt(EndMinute))) - ((parseInt(StartHour) * 60) + (parseInt(StartMinute)))) * 4) - 2.5;

//Generate HTML for blocks

var html_first = '<div data-ix="show-pop-up" class="w-clearfix time-block event-block" style="height:'+BlockHeight+'px; top:'+TopDistance+'px; background-color:'+json.timeslots[i].achtergrondkleur+';">';
if (json.timeslots[i].afbeelding.length > 0) {
var html_mid = '<div class="avatar" style="background-image:url('+json.timeslots[i].afbeelding+');"></div>';
}
else {
html_mid = "";
}
var html_last = '<h4 class="card-title">'+json.timeslots[i].naam+'</h4><div class="time-indication">'+json.timeslots[i].begintijd+'</div><div class="speaker-description">'+json.timeslots[i].functie+'</div><div class="hidden-content"><div class="pop-up-wrapper" style="background-color:'+json.timeslots[i].achtergrondkleur+';"><div class="w-clearfix pop-up-header-background"><div data-ix="hide-pop-up" class="close-icon" id="PopupClose"></div><h3 class="white pop-up-title">'+json.timeslots[i].naam+'</h3><div class="pop-up-subtitle">'+json.timeslots[i].functie+'</div></div><div class="w-clearfix pop-up-body"><div class="pop-up-avatar" style="background-image:url('+json.timeslots[i].afbeelding+');"></div><div class="w-clearfix"><div class="pop-up-card-detail-wrap"><div class="time-label">Begint om</div><div class="pop-up-time-text">'+json.timeslots[i].begintijd+'</div></div><div class="pop-up-card-detail-wrap"><div class="time-label">Eindigt om</div><div class="pop-up-time-text">'+json.timeslots[i].eindtijd+'</div></div><div class="pop-up-card-detail-wrap"><div class="time-label">plek</div><div class="pop-up-time-text">Zaal 1</div></div></div><p class="pop-up-paragraph">'+json.timeslots[i].beschrijving_lang+'</p></div><div class="pop-up-footer"><a href="'+json.timeslots[i].leesmeer_url+'" class="w-button paragraph-button">Meer over deze spreker</a></div></div></div></div>';

var html = html_first+html_mid+html_last;
var TargetDiv = "#Locatie"+f+"Column";

alert("Parent loop increment: "+f);
alert("Child loop increment: "+i);
$(TargetDiv).append(html);
}
});
}

Answer

It starts at f = 6 because your callback doesn't get called until after f equals 6

What you may do is something to the effect of:

for (var f = 0; f < 6; f++) {

  var JSONURL = "http://blabla.com/json";

  $.ajax( JSONURL, {
    dataType: "json"
  })
    .done(handleResponse.bind(null, f));
}

function handleResponse(f, json) {
    for (var i = 0; i < json.timeslots.length; i++) { 

        var StartHour = json.timeslots[i].begintijd.split(":")[0];
        var StartMinute = json.timeslots[i].begintijd.split(":")[1];
        var EndHour = json.timeslots[i].eindtijd.split(":")[0];
        var EndMinute = json.timeslots[i].eindtijd.split(":")[1];

        //Calculate top distance of block in pixels
        if (StartHour < 20) {
            var TopDistance = ((parseInt(StartHour) - 9) * 240) + (parseInt(StartMinute) * 4);

        }

        //Calculate height of block in pixels
        var BlockHeight = ((((parseInt(EndHour) * 60) + (parseInt(EndMinute))) - ((parseInt(StartHour) * 60) + (parseInt(StartMinute)))) * 4) - 2.5;

        //Generate HTML for blocks

        var html_first = '<div data-ix="show-pop-up" class="w-clearfix time-block event-block" style="height:'+BlockHeight+'px; top:'+TopDistance+'px; background-color:'+json.timeslots[i].achtergrondkleur+';">';
        if (json.timeslots[i].afbeelding.length > 0) {
            var html_mid = '<div class="avatar" style="background-image:url('+json.timeslots[i].afbeelding+');"></div>';
        }
        else {
            html_mid = "";
        }
        var html_last = '<h4 class="card-title">'+json.timeslots[i].naam+'</h4><div class="time-indication">'+json.timeslots[i].begintijd+'</div><div class="speaker-description">'+json.timeslots[i].functie+'</div><div class="hidden-content"><div class="pop-up-wrapper" style="background-color:'+json.timeslots[i].achtergrondkleur+';"><div class="w-clearfix pop-up-header-background"><div data-ix="hide-pop-up" class="close-icon" id="PopupClose"></div><h3 class="white pop-up-title">'+json.timeslots[i].naam+'</h3><div class="pop-up-subtitle">'+json.timeslots[i].functie+'</div></div><div class="w-clearfix pop-up-body"><div class="pop-up-avatar" style="background-image:url('+json.timeslots[i].afbeelding+');"></div><div class="w-clearfix"><div class="pop-up-card-detail-wrap"><div class="time-label">Begint om</div><div class="pop-up-time-text">'+json.timeslots[i].begintijd+'</div></div><div class="pop-up-card-detail-wrap"><div class="time-label">Eindigt om</div><div class="pop-up-time-text">'+json.timeslots[i].eindtijd+'</div></div><div class="pop-up-card-detail-wrap"><div class="time-label">plek</div><div class="pop-up-time-text">Zaal 1</div></div></div><p class="pop-up-paragraph">'+json.timeslots[i].beschrijving_lang+'</p></div><div class="pop-up-footer"><a href="'+json.timeslots[i].leesmeer_url+'" class="w-button paragraph-button">Meer over deze spreker</a></div></div></div></div>';

        var html = html_first+html_mid+html_last;
        var TargetDiv = "#Locatie"+f+"Column";

        alert("Parent loop increment: "+f);
        alert("Child loop increment: "+i);
        $(TargetDiv).append(html);
    }
}

What this does is call handleResponse by passing in the value of f at the time that the loop is run.