2

I am playing with angular 2 forms async validation, everything is working fine but then i realised ajax call is made to server on every key press inside input field which is not good for server, i tried many things but nothing works. So please help me to how to deal with this problem.

form: FormGroup;
username: FormControl;
password: FormControl;

constructor(private fb: FormBuilder, private http: Http) {
    this.username = new FormControl("", Validators.compose([
        Validators.required, 
        SignupValidators.CannotContainSpace]),
        this.usernameShouldBeUnique.bind(this));

    this.password = new FormControl("", Validators.compose([Validators.required]));

    this.form = fb.group({
        username: this.username,
        password: this.password
    });
}

Async validation Method:

usernameShouldBeUnique(formControl:FormControl) {

    return new Promise(resolve => {

        let params = new URLSearchParams();
        params.set('username', formControl.value);
        this.http.get('http://localhost:1667/api/users/signup/namecheck', { search: params })
                  .subscribe(data => resolve(null), 
                             error => resolve({ usernameShouldBeUnique: true })
                            );
    });
}
n00dl3
  • 21,213
  • 7
  • 66
  • 76
Godfather
  • 5,711
  • 5
  • 21
  • 27

2 Answers2

1

You can play with Rxjs operators called debounceTime or delay and distinctUntilchanged as shown below,

usernameShouldBeUnique(formControl:FormControl) {



        let params = new URLSearchParams();
        params.set('username', formControl.value);

     return this.http.get('http://localhost:1667/api/users/signup/namecheck', { search: params })

     // .delay(300)                  <---- check this according to your need
        .debounceTime(300)         //<---- wait for 300ms pause in events
        .distinctUntilChanged()    //<---- ignore if next search term is same as previous


        .subscribe(data => resolve(null), 
                             error => resolve({ usernameShouldBeUnique: true })
                            );



}
micronyks
  • 54,797
  • 15
  • 112
  • 146
0

Per this fine answer, you can use the surprisingly-handy setTimeout and clearTimeout to delay your requests:

private timeout;

usernameShouldBeUnique(formControl: FormControl) {
  MY_DELAY = 500;
  clearTimeout(this.timeout);
  return new Promise(resolve => {
    let params = new URLSearchParams();
    params.set('username', formControl.value);
    this.timeout = setTimeout(() => {
      this.http.get('http://localhost:1667/api/users/signup/namecheck', {
          search: params
        })
        .subscribe(data => resolve(null),
          error => resolve({
            usernameShouldBeUnique: true
          })
        );
    }, MY_DELAY);
  });
}

MY_DELAY will cause the request to wait 500 milliseconds for no more validation changes before proceeding.

Community
  • 1
  • 1
Jack Guy
  • 8,346
  • 8
  • 55
  • 86