0
votes

I'm trying to list data from a JSON source.

I loop the data in a $.each, and display it using append.

var result = JSON.parse(response);

if(result.count != 0) {
    $(".modal").find("#search-results").html("<p>" + result.count + " result(s) found:</p>");
    var list = $(".modal").find("#search-results").append("<div class=\"list-group dbsearch-list-group\"></div>").find('div');
    $.each(result.results, function(index, value) {
        var link = list.append('<a href="javascript:;" class="list-group-item p-0 list-group-item-action" id="autosearch" data-id="' + value.itemid + '" data-instantclose="true"></a>').find('a');
        var col = link.append('<div class="row"></div>').find('div');
            col.append('<div class="col-sm py-0 col-md-auto"><img src="' + value.icon + '" class="dbsearch-icon" /></div>');
            col.append('<div class="col-sm py-0 align-self-center">' + value.title + '</div>');
    });
} else {
    $(".modal").find("#search-results").html("<p>No results found.</p>");
}

For some odd reason, it outputs an error after a couple of loops:

jquery-3.3.1.min.js:2 Uncaught RangeError: Maximum call stack size exceeded

enter image description here

I've Googled the error and they say it's caused by an infinite loop. The JSON response entries can be quite long, around 300 items.

Even then, it shouldn't really output this if I'm correct. Why is this happening?

1
It's caused by infinite recursion, not an infinite loop. - Barmar
If you look in the call stack in the JavaScript debugger you should see what function is being called repeatedly. - Barmar
@Barmar Sorry, where do I find this? - Appel Flap
In the Sources tab of Developer Tools. - Barmar
@Barmar I've paused the page after it froze: i.imgur.com/bICsdeo.png - Appel Flap

1 Answers

2
votes

I don't think your chained functions of the form:

x = y.append("some HTML element").find("type of that element");

are doing what you expect. I think you're trying to set x to the element that you just appended. But it actually sets it to a collection of all the elements that have been appended so far. And when y is one of these collections, you're appending the new HTML to all of them, and then finding all of the elements that have been appended that way. This is causing exponential explosion of the number of elements being created and appended.

What I think you want is this:

x = $("some HTML element").appendTo(y);

So the full code should be:

var result = JSON.parse(response);

if(result.count != 0) {
    $(".modal").find("#search-results").html("<p>" + result.count + " result(s) found:</p>");
    var list = $("<div class=\"list-group dbsearch-list-group\"></div>").appendTo(".modal");
    $.each(result.results, function(index, value) {
        var link = $('<a href="javascript:;" class="list-group-item p-0 list-group-item-action" id="autosearch" data-id="' + value.itemid + '" data-instantclose="true"></a>').appendTo(list);
        var col = $('<div class="row"></div>').appendTo(link);
        col.append('<div class="col-sm py-0 col-md-auto"><img src="' + value.icon + '" class="dbsearch-icon" /></div>');
        col.append('<div class="col-sm py-0 align-self-center">' + value.title + '</div>');
    });
} else {
    $(".modal").find("#search-results").html("<p>No results found.</p>");
}