Angular 2 change event on every keypress

Angular

Angular Problem Overview


The change event is only called after the focus of the input has changed. How can I make it so that the event fires on every keypress?

<input type="text" [(ngModel)]="mymodel" (change)="valuechange($event)" />
{{mymodel}}

The second binding changes on every keypress btw.

Angular Solutions


Solution 1 - Angular

I just used the event input and it worked fine as follows:

in .html file :

<input type="text" class="form-control" (input)="onSearchChange($event.target.value)">

in .ts file :

onSearchChange(searchValue: string): void {  
  console.log(searchValue);
}

Solution 2 - Angular

Use ngModelChange by breaking up the [(x)] syntax into its two pieces, i.e., property databinding and event binding:

<input type="text" [ngModel]="mymodel" (ngModelChange)="valuechange($event)" />
{{mymodel}}

valuechange(newValue) {
  mymodel = newValue;
  console.log(newValue)
}

It works for the backspace key too.

Solution 3 - Angular

The (keyup) event is your best bet.

Let's see why:

  1. (change) like you mentioned triggers only when the input loses focus, hence is of limited use.
  2. (keypress) triggers on key presses but doesn't trigger on certain keystrokes like the backspace.
  3. (keydown) triggers every time a key is pushed down. Hence always lags by 1 character; as it gets the element state before the keystroke was registered.
  4. (keyup) is your best bet as it triggers every time a key push event has completed, hence this also includes the most recent character.

So (keyup) is the safest to go with because it...

  • registers an event on every keystroke unlike (change) event
  • includes the keys that (keypress) ignores
  • has no lag unlike the (keydown) event

Solution 4 - Angular

<input type="text" [ngModel]="mymodel" (keypress)="mymodel=$event.target.value"/>
{{mymodel}}

Solution 5 - Angular

A different way to handle such cases is to use formControl and subscribe to it's valueChanges when your component is initialized, which will allow you to use rxjs operators for advanced requirements like performing http requests, apply a debounce until user finish writing a sentence, take last value and omit previous, ...

import {Component, OnInit} from '@angular/core';
import { FormControl } from '@angular/forms';
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';

@Component({
  selector: 'some-selector',
  template: `
    <input type="text" [formControl]="searchControl" placeholder="search">
  `
})
export class SomeComponent implements OnInit {
  private searchControl: FormControl;
  private debounce: number = 400;

  ngOnInit() {
    this.searchControl = new FormControl('');
    this.searchControl.valueChanges
      .pipe(debounceTime(this.debounce), distinctUntilChanged())
      .subscribe(query => {
        console.log(query);
      });
  }
}

Solution 6 - Angular

The secret event that keeps angular ngModel synchronous is the event call input. Hence the best answer to your question should be:

<input type="text" [(ngModel)]="mymodel" (input)="valuechange($event)" />
{{mymodel}}

Solution 7 - Angular

<input type="text" (keypress)="myMethod(myInput.value)" #myInput />

archive .ts

myMethod(value:string){
...
...
}

Solution 8 - Angular

For Reactive Forms, you can subscribe to the changes made to all fields or just a particular field.

Get all changes of a FormGroup:

this.orderForm.valueChanges.subscribe(value => {
    console.dir(value);
});

Get the change of a specific field:

this.orderForm.get('orderPriority').valueChanges.subscribe(value => {
    console.log(value);
  });

Solution 9 - Angular

What you're looking for is

<input type="text" [(ngModel)]="mymodel" (keyup)="valuechange()" />
{{mymodel}}

Then do whatever you want with the data by accessing the bound this.mymodel in your .ts file.

Solution 10 - Angular

I managed to get this solved in Angular 11 by using the below code:

<input type="number" min="0" max="50" [value]="input.to" name="to"
        (input)="input.to=$event.target.value; experienceToAndFrom()">

And, the experienceToAndFrom() is a method in my component.

PS: I tried all the above solutions, but didn't work.

Solution 11 - Angular

In my case, the solution is:

[ngModel]="X?.Y" (ngModelChange)="X.Y=$event"

Solution 12 - Angular

I've been using keyup on a number field, but today I noticed in chrome the input has up/down buttons to increase/decrease the value which aren't recognized by keyup.

My solution is to use keyup and change together:

(keyup)="unitsChanged[i] = true" (change)="unitsChanged[i] = true"

Initial tests indicate this works fine, will post back if any bugs found after further testing.

Solution 13 - Angular

This question has been answered with multiple ways. However, if you would like to look at another way, specific to adding some delay before you take any action on change event then you can use the debounceTime() method with angular form valuechanges(). This code need to be added in ngOnInit() hook or create a seprate method and call it from ngOnInit().

  ngOnInit(): void {
    this.formNameInputChange();
  }

  formNameInputChange(){
    const name = this.homeForm.get('name'); // Form Control Name
    name?.valueChanges.pipe(debounceTime(1000)).subscribe(value => {
      alert(value);
    });
  }
  // this is reactive way..
  homeForm = this.fb.group({
    name:['']
  });

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondanielView Question on Stackoverflow
Solution 1 - AngularRamy FetehaView Answer on Stackoverflow
Solution 2 - AngularMark RajcokView Answer on Stackoverflow
Solution 3 - AngularSagarView Answer on Stackoverflow
Solution 4 - AngularGünter ZöchbauerView Answer on Stackoverflow
Solution 5 - AngularSalem OuerdaniView Answer on Stackoverflow
Solution 6 - AngularEmeka ObianomView Answer on Stackoverflow
Solution 7 - AngularUlric MerguiçoView Answer on Stackoverflow
Solution 8 - AngularstayingcoolView Answer on Stackoverflow
Solution 9 - AngularSanket BerdeView Answer on Stackoverflow
Solution 10 - AngularSanjiv PradhanView Answer on Stackoverflow
Solution 11 - Angularhatem htiraView Answer on Stackoverflow
Solution 12 - Angularuser9273992View Answer on Stackoverflow
Solution 13 - AngularPrabhat MauryaView Answer on Stackoverflow