An-droid
An-droid

Reputation: 6485

Input debounce with angular 2

In an application I need to send an event on input debounce.

I'm trying this :

   @ViewChild('messageInput') messageInput: ElementRef;
   private inputTimeOutObservable: any;

    setTypingTimeOut(){
          this.inputTimeOutObservable = Observable.fromEvent(this.messageInput.nativeElement, 'input')
            .map((event: Event) => (<HTMLInputElement>event.target).value)
            .debounceTime(1000)
            .distinctUntilChanged()
            .subscribe(data => {
              this.sendEvent();
            });
    }
    ngOnDestroy() {
        if (this.inputTimeOutObservable) {
          this.inputTimeOutObservable.unsubscribe();
          this.inputTimeOutObservable = null;
        }
      }

The input do other stuff but here it is :

 <input #messageInput id="message" type="text" (ngModelChange)="inputTextChanges($event)"
               [(ngModel)]="messageValue" (keyup)='keyUp.next($event)'>

The event is not fired and I don't see why here. Any idea ?

Upvotes: 1

Views: 1979

Answers (2)

alsami
alsami

Reputation: 9845

If you don't mind using a reactive form control you could do the following:

import { FormControl } from '@angular/forms';

public myCtrl: FormControl = new FormControl();
myCtrl.valueChanges.debounceTime(1000).subscribe(value => ...);

And your template gets cleaner:

<input #messageInput id="message" type="text" [formControl]="myCtrl">

Upvotes: 0

abdul-wahab
abdul-wahab

Reputation: 2272

Based on you code, here's a working example:

component.html

<input #messageInput id="message" type="text" [(ngModel)]="messageValue">

component.ts

import {Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import {Observable} from "rxjs/Rx";

@Component({
  selector: 'app-input-debounce',
  templateUrl: './input-debounce.component.html',
  styleUrls: ['./input-debounce.component.css']
})
export class InputDebounceComponent implements OnInit {
  @ViewChild('messageInput') messageInput: ElementRef;
  public messageValue: string = "";
  private inputTimeOutObservable: any;

  constructor() {
  }

  ngOnInit() {
  }

  ngAfterViewInit() {
    this.setTypingTimeOut();
  }

  setTypingTimeOut() {

    this.inputTimeOutObservable = Observable.fromEvent(this.messageInput.nativeElement, 'input')
      .map((event: Event) => (<HTMLInputElement>event.target).value)
      .debounceTime(1000)
      .distinctUntilChanged()
      .subscribe(data => {
        console.log(this.messageValue);
        console.timeEnd("Input changed after."); // No matter how frequent you type, this will always be > 1000ms
        console.time("Input changed after."); // start track input change fire time
      });
  }

}

Upvotes: 1

Related Questions