ValueChanges is triggered on blur when input is of type Number

Viewed 830

I was quite surprised to find out that unlike other type of HTML inputs, typing inside an input of type Number would get valueChanges triggered on blur, as well as clicking on the spinners (the little arrows on the side) will get valueChanges triggered twice, is this an expected behavior? am I missing something?

Component:

export class AppComponent {

  textControl = new FormControl();
  numberControl = new FormControl();

  ngOnInit(): void {
    this.textControl.valueChanges.subscribe(console.log)
    this.numberControl.valueChanges.subscribe(console.log)
  }

}

Template:

<input type="text" [formControl]="numberControl">
<input type="number" [formControl]="textControl">

Here's Stackblitz demo

2 Answers

This is a known issue which has been already fixed in Angular 10

Forked Stackblitz with Angular 10

Prior to this fix Angular listed to two events:

host: {
    '(change)': 'onChange($event.target.value)',
    '(input)': 'onChange($event.target.value)',

Starting from Angular 10 it listens only for one:

host: {
     '(input)': 'onChange($event.target.value)'

It looks it's an issue in some versions of Angular. Someone also reported the same issue on Github.

https://github.com/angular/angular/issues/26054

It looks it's fixed in Angular 10 as long as @alon's demo is working.

I believe it isn't a critical issue for you.

However, one simple solution is to use distinctUntilChanged operator.

this.numberControl.valueChanges
  .pipe(distinctUntilChanged())
  .subscribe(console.log)
Related