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>
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With