Why is my event handler always one keystroke behind, and how does $timeout fix this?

Issue

I’m totally confused as to why my keypress event handler is always one keystroke behind. http://plnkr.co/edit/w3FAXGd5zjrktO6DgOpD?p=preview

<body ng-controller="myController">
  <form>
    <input ng-keypress="handleKeypress($event)" />
  </form>
</body>

Controller:

myapp.controller('myController', function($scope, $timeout){

    $scope.handleKeypress = function(ev){

      console.log(ev.target.value); //always one keystroke behind

      //$timeout(function(){console.log(ev.target.value);}); //works!

    };
}); 

Why is $timeout necessary and why/how does it work? (A newbie-friendly answer is preferable)

I understand that with the keypress event the character hasn’t yet been inserted into the DOM, but I’m confused because the Hello World example at angularjs.org responds before a key is released. Their example doesn’t use a custom event handler, but clearly Angular is updating the model before the keyup event, so I’d like understand more about doing this in a custom event handler.

idursun’s answer points out that event.which is available on keypress, and I thought Angular might be using String.fromCharCode(), but I don’t see anything in the Angular source to this effect.

Solution

Because event target in your example is an input element and keystroke has not been processed by the element yet so value of that element is always one keystroke lagging. This gives a chance to the event handler to reject key press.

You can check pressed key value by looking at which field of the event object.

Answered By – idursun

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published