Too much recursion - jquery - autocomplete

591 views Asked by At

So here is my autocomplete functionality:

var selected;
    var itemAdded = false;

    $('.js-main-search').autocomplete({
        minLength: 3,


        source: function(request, response) {
            $.getJSON('/dashboard/searchDocumentsAndCompanies.do',
                { q: request.term},
                function(data) {
                    if(data.length == 0){
                        data = [
                            {name: 'No matches found', resultType: 'COMPANY', noResults: true},
                            {name: 'No matches found', resultType: 'BRANCHES', noResults: true},
                        ];
                    }
                    data.unshift({name: 'Search from documents »', reqQuery: request.term, docSearch:true});
                    response(data);
                });
        },
        select: function( event, ui ) {

            event.preventDefault();
            selected = true;
            if(ui.item.docSearch && !itemAdded){
                $(".textbox.ui-front li:eq(1)").before('<li class="search-category ui-menu-item">Documents</li>');
                itemAdded = true;
            }
        }
    });

    $('.js-main-search').data("uiAutocomplete").close = function(event) {
        if (!selected){
            $('.js-main-search').data("uiAutocomplete").close.apply( this, arguments );
        }
        selected = false;
    };

    $('.js-main-search').data('uiAutocomplete')._renderItem = function( ul, item ) {
        itemAdded = false;
        item.value = item.name;
        var $el = $( "<li>" ).append(item.value);
        if(item.docSearch){
            $el.addClass( "search-documents-btn" );
            $el.one('click', function (e) {

                e.preventDefault();
                console.log(ul.children());
            });
        }
        if(!item.noResults && !item.docSearch){
            $el.append('<div class="meta"><a href="#">Documents</a> | <a href="#">Company page</a></div>');
        }
        $el.appendTo( ul );
        return $el;
    };

    $('.js-main-search').data('uiAutocomplete')._renderMenu = function(ul, items) {
        var companiesResults = true;
        var branchesResults = true;
        var that = this,currentCategory = '';

        $.each(items, function(index, item) {
            var li;
            if (item.resultType != currentCategory && !item.docSearch) {
                var categoryTitle = '';
                if(item.resultType == 'COMPANY'){
                    categoryTitle = 'Companies';
                    companiesResults = false;
                } else{
                    categoryTitle = 'Branches'
                    branchesResults = false;
                }
                ul.append('<li class="search-category">'+categoryTitle+'</li>');
                currentCategory = item.resultType;
            }

            li = that._renderItemData(ul, item);

            if (item.resultType) {
                item.value = item.name;
                li.attr('aria-label', item.resultType + ' : '+ item.value);
            }

        });

        if(companiesResults && branchesResults){
            ul.append('<li class="search-show-more-btn">Show more</li>');
        }

    };

When I am starting to enter search keyword sometimes it gives me the following error in console: "Too much recursion", but I don't understand why. Any suggestions are welcome.

1

There are 1 answers

2
muchwow On BEST ANSWER

Usually when you get a stack overflow error, it is because you have a recursion for which no exit condition exist or is triggered. Looking at your code, here's the function that causes the problem.

$('.js-main-search').data("uiAutocomplete").close = function (event) {
    if (!selected) {
        $('.js-main-search').data("uiAutocomplete").close.apply(this, arguments);
    }
    selected = false;
};

I guess the selected = false; should be inside the if statement before the recursive call like so:

    $('.js-main-search').data("uiAutocomplete").close = function (event) {
        if (!selected) {
            selected = false;
            $('.js-main-search').data("uiAutocomplete").close.apply(this, arguments);
        }
    };