0

I have this piece of code

inputElem.on('keydown', function(event) {
                if (event.which === 38) { // up
                    $scope.inc();
                    promise = $interval($scope.inc(), 300);
                } else if (event.which === 40) { // down
                    $scope.dec();
                    promise = $interval($scope.dec(), 300);
                }
            });

inputElem.on('keyup', function(event) {
            if (event.which === 38 || event.which === 40) {
                $interval.cancel(promise);
            }
        });

I am basically using it to increase/decrease the values in an edit box by 1 using the up and down arrows. So when a user keeps the up/down arrow pressed the value keeps changing. My issue is that it seems to increase/decrease the value twice even if I press one of the arrows really quick. I put a console.log() in the inc() and dec() functions and they are indeed called twice even If I change the time to 3 seconds or somethign like that. As far as I know, interval doesn't all the recurring function once it is initialise but rather it waits the corresponding interval the first time. Am I wrong? What could be the problem?

Andreas Andreou
  • 818
  • 10
  • 31
  • 3
    Remove `()` in `$interval($scope.inc(), 300);`. USE `$interval($scope.inc, 300);` Removing the braces will pass the function reference instead of calling it. – Tushar Jun 02 '16 at 11:41
  • Thanks, @Tushar. I missed the need for references. It works now, although if I keep it pressed and then unpress it it doesn't stop increasing but that is anothre issue. I will look into it – Andreas Andreou Jun 02 '16 at 12:45
  • I figured it out. Keeping a key pressed fires multiple 'keydown' events but because I don't release the key the 'keyup' event is not fired and the promise not cancelled. So it is being replaced by the next promise and so will keep calling the funciton because it is lost and can't pass it to the cancel function. So I have to check if a promise exists band cancelling it before creating a new one – Andreas Andreou Jun 02 '16 at 13:09

1 Answers1

1

You are calling the function twice every time.

$scope.inc(); //function called
promise = $interval($scope.inc(), 300); //call it again 300 ms later in the promise;

Also, the proper usage of interval is (reference, time) but you are sending the whole function in with $scope.inc(). To pass a function by reference you eliminate the (), as Tushar said, How ever that is not the reason the function is being called twice. You coded it that way.

Your backwards with timeout and interval. Timeout is once, interval happens every interval. 'setInterval' vs 'setTimeout'

Community
  • 1
  • 1
Jon Crawford
  • 193
  • 11