4

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>

2 Answers 2

4

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

Sign up to request clarification or add additional context in comments.

1 Comment

Hello ! Would you know the answer to this ? stackoverflow.com/questions/44044163/…
0

To add to yurzui's second answer:

this works:

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

so does this:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.