diff --git a/src/typeahead/test/typeahead.spec.js b/src/typeahead/test/typeahead.spec.js index f42bad15c0..8f1bd3fdf7 100644 --- a/src/typeahead/test/typeahead.spec.js +++ b/src/typeahead/test/typeahead.spec.js @@ -183,6 +183,41 @@ describe('typeahead tests', function () { $timeout.flush(); expect(element).toBeOpenWithActive(1, 0); })); + + it('should cancel old timeouts when something is typed within waitTime', inject(function ($timeout) { + var values = []; + $scope.loadMatches = function(viewValue) { + values.push(viewValue); + return $scope.source; + }; + var element = prepareInputEl("
"); + changeInputValueTo(element, 'first'); + changeInputValueTo(element, 'second'); + + $timeout.flush(); + + expect(values).not.toContain('first'); + })); + + it('should allow timeouts when something is typed after waitTime has passed', inject(function ($timeout) { + var values = []; + + $scope.loadMatches = function(viewValue) { + values.push(viewValue); + return $scope.source; + }; + var element = prepareInputEl("
"); + + changeInputValueTo(element, 'first'); + $timeout.flush(); + + expect(values).toContain('first'); + + changeInputValueTo(element, 'second'); + $timeout.flush(); + + expect(values).toContain('second'); + })); }); describe('selecting a match', function () { diff --git a/src/typeahead/typeahead.js b/src/typeahead/typeahead.js index 0bf5d004fc..b4541def17 100644 --- a/src/typeahead/typeahead.js +++ b/src/typeahead/typeahead.js @@ -133,19 +133,20 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position']) //we need to propagate user's query so we can higlight matches scope.query = undefined; + //Declare the timeout promise var outside the function scope so that stacked calls can be cancelled later + var timeoutPromise; + //plug into $parsers pipeline to open a typeahead on view changes initiated from DOM //$parsers kick-in on all the changes coming from the view as well as manually triggered by $setViewValue modelCtrl.$parsers.push(function (inputValue) { - var timeoutId; - resetMatches(); if (inputValue && inputValue.length >= minSearch) { if (waitTime > 0) { - if (timeoutId) { - $timeout.cancel(timeoutId);//cancel previous timeout + if (timeoutPromise) { + $timeout.cancel(timeoutPromise);//cancel previous timeout } - timeoutId = $timeout(function () { + timeoutPromise = $timeout(function () { getMatchesAsync(inputValue); }, waitTime); } else {