Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Async Validator not working with Template driven Forms in Angular

I have created a Async Validator for my Template Driven form .

import {Directive, forwardRef} from "@angular/core";
import {NG_ASYNC_VALIDATORS, Validator, AbstractControl, AsyncValidator} from "@angular/forms";
import {Observable} from "rxjs";


@Directive({
  selector: '[asyncValidator][ngModel]',
  providers: [{
    provide: NG_ASYNC_VALIDATORS, useExisting: forwardRef(() => AsyncAgeValidator), multi: true

  }]
})

export class AsyncAgeValidator implements Validator{

  validate(c: AbstractControl): Observable<{[key : number] : any}>{
      return this.validateAgeObservable(c.value);
  }

  validateAgeObservable( age: number ) {
    return new Observable(observer => {

      if( age === 20 ) {
        observer.next(null);
      } else {
        observer.next({asyncInvalid: true});
        console.log('validate');
      }
    });
  }

  }


}

I am using it in my Template as follows but i do not get the Error message i expect from the validator in the template. the call is going to the validator but i guess it is not registering the observable in the component.

<md-input-container>
  <input mdInput type="number" name="age" [(ngModel)]="user.age" placeholder="Age" required asyncValidator>
</md-input-container>
like image 206
Rahul Avatar asked Oct 27 '25 04:10

Rahul


1 Answers

Your observable never completes, so Angular does not know when to change the form status. So remember your observable must to complete.

You can accomplish this in many ways:

1) manually to call complete() method on observer:

validateAgeObservable( age: number ) {
  return new Observable(observer => {
    observer.next(age === 20 ? null : {asyncInvalid: true});
    observer.complete();
  });
}

Plunker Example

2) call first() method:

validate(c: AbstractControl): Observable<{[key : number] : any}>{
    return this.validateAgeObservable(c.value).first();
}

validateAgeObservable( age: number ) {
  return new Observable(observer => {
    observer.next(age === 20 ? null : {asyncInvalid: true});
  });
}

Plunker Example

like image 196
yurzui Avatar answered Oct 29 '25 21:10

yurzui



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!