Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get Validators from the formControl directly?

enter image description here

enter image description here

enter image description here

I have an email field, and I added two validators(required, email), I want to check validation status on the input event to call API check dose a member of my system when it's valid, if it's invalid don't to call API and don't show error message on the page.

I will show error message on blur event(focusOut email's input),firstly I used formControl.validator(formControl) to trigger validators and check formControl.valid,I got valid status successful but it will show error message on the page because I subscribed statsuChange to show an error message when status equal to invalid.

currently, I save validators in a variable and pass to initEmailChaingeEvent() to check validation status without statusChange event. It's can work, but I think it's not a good way, here's an example of my implementation:

live example

export class AppComponent {
  public sampleForm: FormGroup;

  @ViewChild('emailElm')
  emailElm: ElementRef;

  ngOnInit() {
    this.initForm();
  }

  initForm() {
    const emailValidtors = [
      Validators.required,
      Validators.email
    ]

    const emailFC = new FormControl(null, {
      validators: emailValidtors,
      updateOn: 'blur'
    });
    //
    this.sampleForm = new FormGroup({
      'email': emailFC
    });
    //
    this.initEmailChaingeEvent({
      emailFC: emailFC,
      validtors: emailValidtors
    });
    //
    this.sampleForm.valueChanges.subscribe((val) => {
      console.log('_blue event:valueChanges', val)
    });
    //
    this.initShowErrorMsgEvent({
      fc: emailFC
    });
  }

  private initEmailChaingeEvent(arg: {
    emailFC: FormControl,
    validtors: any[]
  }) {
    fromEvent(this.emailElm.nativeElement, 'input')
      .pipe(debounceTime(500))
      .subscribe((event: Event) => {
        const currentEmail = (event.target as HTMLInputElement).value;
        // check is valid
        // **quention** : how can I get validtors from fromcontrol self 
        // if I use  arg.emailFC.validator(arg.emailFC) to ehcek status , it will trigger oberservable in initShowErrorMsgEvent(),
        //  but I just want to got valid result , I don't want to show error msg on UI at this time

        for (const validator of arg.validtors) {
          const inValid = validator(arg.emailFC);
          if (inValid) {
            console.log('input event:invalid', currentEmail);
            return;
          }
        }
        // **do sometheng when all valid**
        console.log('input event:call API , email:',currentEmail );
      });
  }

  private initShowErrorMsgEvent(arg: {
    fc: FormControl,
  }) {
    arg.fc.statusChanges
      .subscribe((status) => {
        // console.log('status' , status);
        if (status === 'INVALID') {
          // show error msg....
          console.log('_show error msg by antoher component');
        }
      });
  }
}
<form [formGroup]="sampleForm">
  <input formControlName="email" #emailElm >
</form>
like image 517
Chunbin Li Avatar asked Jun 01 '18 15:06

Chunbin Li


1 Answers

You over-complicated the task. First, declare your form, and control validators. If you compose a validator from a list of validators, they will be checked in order of definition. So, first the required, then "if it's valid email", and last you custom validator will check if it's unique

 ....
 this.emailForm = this.fb.group({
       emailAddress: [null, Validators.compose([Validators.required, Validators.email, uniqueEmailValidator()])]
 });
 ...

Then you create your custom validator for checking the user email by the API. More info on custom validators: Angular docs

function uniqueEmailValidator(){
    ...
}
like image 165
Zsolt Tolvaly Avatar answered Oct 31 '22 09:10

Zsolt Tolvaly