0

I have a recursive SetTimeout function that clicks a filter on my page after the filters have loaded (they're loaded through Ajax, so not available immediately on page load).

$scope.clickFilter = function () {
    var filter = $('.filter-item')
        .find('input[value="' + $scope.activeFilter + '"]');

    if (filter.length < 1) {
        setTimeout($scope.clickFilter(), 1000);
    } else {
        $(filter).trigger("click");
    }
}

However, when the filters take a long time to load, I get "Uncaught RangeError: Maximum call stack size exceeded(…)"

How do I prevent this and make sure it runs until completion?

Erica Stockwell-Alpert
  • 4,624
  • 10
  • 63
  • 130

1 Answers1

3

The problem is here:

  setTimeout($scope.clickFilter(), 1000); 

Putting () after the function reference means that you want the function to be called, immediately, at that point in the code. What you probably want instead is something like:

  setTimeout($scope.clickFilter.bind($scope), 1000);

which will

  • pass a function reference to setTimeout(), as is required, and
  • ensure that the function will be invoked with the proper this value (what the .bind() part does)

Once you get it working, the term "recursive" isn't really appropriate. Yes, the function is referencing itself when it arranges for the call after the timer expires, but it's not directly calling itself; it's asking something else (the timer mechanism) to call it later.

Pointy
  • 405,095
  • 59
  • 585
  • 614