0

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?

13
  • It's caused by infinite recursion, not an infinite loop. Commented Mar 13, 2019 at 19:32
  • If you look in the call stack in the JavaScript debugger you should see what function is being called repeatedly. Commented Mar 13, 2019 at 19:34
  • @Barmar Sorry, where do I find this? Commented Mar 13, 2019 at 19:36
  • In the Sources tab of Developer Tools. Commented Mar 13, 2019 at 19:38
  • @Barmar I've paused the page after it froze: i.imgur.com/bICsdeo.png Commented Mar 13, 2019 at 19:44

1 Answer 1

2

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>");
}
Sign up to request clarification or add additional context in comments.

1 Comment

Yep, totally works! Appreciate the help a lot, Barmar!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.