27

my Angular code look like this >

<input type='text' (blur)='saveData()'>
<button (click)='navigateToPage2()'>

Jumping from textbox being focused to the button click, there is racing condition between two events.

Problem is button click gets ignored because the blur event fires first and brings the spinner on the screen while its making server call to save data.

How do I solve this exact problem?

Is there a hack to make click event fire before blur event ?

Claies
  • 22,124
  • 4
  • 53
  • 77
Nick Thakkar
  • 862
  • 1
  • 9
  • 13
  • it's like you're listening to two person, who speaks first will be recognized first. I am not sure if it's possible but you can try custom events if you want. – Roljhon Apr 11 '17 at 20:24
  • what is the code for saveData and navigateToPage2? – Our_Benefactors Apr 11 '17 at 20:32
  • Well is the saveData asynchronous? impossible to tell from your code sniplet. My guess is you need to make the navigate code aware of open requests and wait until it is complete... – epascarello Apr 11 '17 at 20:32
  • 2
    I'm late, but in case someone else can use this solution, you can try to put the function of saving data within a timeout function: `setTimeout( () => this.saveData(), 100 );` – lorenago Mar 08 '19 at 11:36

3 Answers3

41

Instead of such hack to fire click before blur event try following solution :

To understand this better you need to know this Order in which specific event fires:

  1. mouse down
  2. blur
  3. mouse up
  4. click

You can use this order to work in your favor in this case.

Try using Mousedown event instead and that will fire before blur event.

Also, try running this code snippet. It will help you understand the above order

    Type first in text box below and then click button <br/>
    <input type='text' onblur="console.log('blur');" />

    <button onclick="console.log('click')" 
      onmouseup="console.log('mouseup')" 
      onmousedown="console.log('mousedown')" > Type first and then this click button</button>
Nick Thakkar
  • 862
  • 1
  • 9
  • 13
  • 14
    The only problem with using the mousedown directly is that a user does not expect an action to occur with the mousedown, only after the mouseup, and only when the mouseup occurs on the same element where the mousedown occurred, that is, a click event doesn't fire if you mousedown, move your mouse and then mouseup. Sometimes I click something I didn't mean to, move the mouse away before I let the button go and I expect the action not to take place. – Ruan Mendes Apr 11 '17 at 20:54
  • Also, thanks @JuanMendes . I don't see this as an issue for my app. But really appreciate your input. – Nick Thakkar Apr 11 '17 at 21:05
  • @NickThakkar But how does it work with the left mouse only? onMouseDown trigger all click events: left-click, right-click... – Nam Lee Nov 24 '20 at 04:12
6

According to this example you can also use e.preventDefault on mouseDown event : https://codepen.io/mudassir0909/pen/eIHqB (he used jquery but it should be the same with an other lib)

Sylvain DNS
  • 137
  • 2
  • 5
-2

If you are listening on (blur)="onBlur()" wrap the content of onBlur() in a setTimout with duration 100 ms or more.

Samer
  • 3,848
  • 4
  • 25
  • 24
  • While this will work, there is a better, more reliable way of accomplishing this task described in some of the other replies. https://stackoverflow.com/a/59503238/2443197 – Scala Enthusiast Apr 20 '23 at 09:00