cdwyer
cdwyer

Reputation: 697

Multiple .getJSON in a for loop

Trying to reference two separate JSON (.txt) files, the second of which relies on values from the first. The finished product should be an h4 title, with a "Spring" and "(variable) teacher's last name" underneath. Instead, I'm getting all the headers h4-s listed out each time, followed by an increasing (by one) number of the values. Example of how it's turning out:

<first h4>
<second h4>
<third h4>

spring
------
name associated with first h4


<first h4>
<second h4>
<third h4>

spring
------
name associated with first h4

spring
------
name associated with second h4


<first h4>
<second h4>
<third h4>

spring
------
name associated with first h4

spring
------
name associated with second h4

spring
------
name associated with third h4

I think it might have something to do with getJSON being asynchronous...here's the javascript:

<script>
$(document).ready(function() {
    $.getJSON(("degree.txt"), function(data) {
        var courselisting = "";
        for (var i in data) {
            var teacherfirst = data[i].year.spring.firstname;
            var teacherlast = data[i].year.spring.lastname;

            courselisting+= '<div class="grid">';
            courselisting+= '<div class="col-1-1"><h4 class="ci-header ci-round">' + data[i].course + ', ' + data[i].credits + ' Credit Hour(s)</h4></div>';
            $.getJSON(( "/programs/course-information/faculty/" + teacherfirst + teacherlast + ".txt"), function(data) {
                var lastname = data.lastname;
                var url = data.url;

                courselisting+= '<div class="col-1-4"><div class="col-1-3"><p class="small head">Spring<br></p><p class="small"><a id="" class="hlight" href="' + url + '" target="new">' + lastname + '</a></p></div></div></div>';
                document.getElementById("schedule-container").innerHTML+=courselisting;
            });
        };
    });
});
</script>

Thanks for any help you guys can offer!

Upvotes: 0

Views: 936

Answers (2)

Ben McCormick
Ben McCormick

Reputation: 25728

The callbacks will not run until the loop has run through and completed. At that point courselisting will have reached its final value.

You can wrap it in a closure to avoid this.

Something like this:

$(document).ready(function() {
    $.getJSON(("degree.txt"), function(data) {
        var courselisting = "";
        for (var i in data) {
            var teacherfirst = data[i].year.spring.firstname;
            var teacherlast = data[i].year.spring.lastname;

            courselisting+= '<div class="grid">';
            courselisting+= '<div class="col-1-1"><h4 class="ci-header ci-round">' + data[i].course + ', ' + data[i].credits + ' Credit Hour(s)</h4></div>';
            $.getJSON(( "/programs/course-information/faculty/" + teacherfirst + teacherlast + ".txt"), function(_data,_listing){
                innerFunc(_data,_listing);
            }(data,courselisting));
        };
    });
    function innerFunc(data,courselisting) {
                var lastname = data.lastname;
                var url = data.url;

                courselisting+= '<div class="col-1-4"><div class="col-1-3"><p class="small head">Spring<br></p><p class="small"><a id="" class="hlight" href="' + url + '" target="new">' + lastname + '</a></p></div></div></div>';
                document.getElementById("schedule-container").innerHTML+=courselisting;
            }
});

Upvotes: 0

David Gilbertson
David Gilbertson

Reputation: 4883

You can force jQuery to wait until an AJAX call is complete before doing something else using $.when. For example, wrap your two calls in two functions:

$.when($.getJSON('firstFile.txt')).done(function () {
  $.getJSON('secondFile.txt');
  doSomethingWithResults();
});

See when, done and then for more info.

Upvotes: 1

Related Questions