Expected validator to return Promise or Observable

2020-05-18 04:45发布

问题:

Im trying to do a custom validation on Angular 5 but I'm facing the following error

Expected validator to return Promise or Observable

I just want to return an error to the form if the value doesnt match the required, heres my code:

This is the component where is my form

  constructor(fb: FormBuilder, private cadastroService:CadastroService) {
    this.signUp = fb.group({
      "name": ["", Validators.compose([Validators.required, Validators.minLength(2)])],
      "email": ["", Validators.compose([Validators.required, Validators.email])],
      "phone": ["", Validators.compose([Validators.required, Validators.minLength(5)])],
      "cpf": ["", Validators.required, ValidateCpf]
    })     
   }

This code is in the file with the validation I want to implement:

import { AbstractControl } from '@angular/forms';

export function ValidateCpf(control: AbstractControl){
    if (control.value == 13445) {
        return {errorCpf: true}
    }
    return null;
}

Can someone help me? Does that type of validation only work with observables or can I do i without being a promise or observable? thanks

回答1:

It means that you have to add multiple validators in array

. Example:

With Error

profileFormGroup = {
  budget: [null, Validators.required, Validators.min(1)]
};

Above one throws error that validator to return Promise or Observable

Fix:

profileFormGroup = {
  budget: [null, [Validators.required, Validators.min(1)]]
};

Explanation:

In angular Reactive form validation done by using in-built validators which could given in array in 2nd postion, when multiple validators used.

FIELD_KEY: [INITIAL_VALUE, [LIST_OF_VALIDATORS]]



回答2:

The following should work :

  "cpf": ["", [Validators.required, ValidateCpf]]

the arguments the form control expects are the following :

constructor(formState: any = null, 
            validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null,
            asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null)

from https://angular.io/api/forms/FormControl



回答3:

Validators.compose() is redundant;

You can just pass an array. OP’s problem is caused by failure to wrap the validators in [] to make them an array, hence the minLength() one is assumed to be async and the resulting error message.

I hope, this solution will help you. Thanks.



回答4:

error: userName:['',[Validators.required,Validators.minLength(3)],forbiddenNameValidator(/password/)],

ans: userName:['',[Validators.required,Validators.minLength(3),forbiddenNameValidator(/password/)]],

validators use only second parameter in inside array. not for outside array



回答5:

If you add multiple validators, then you need to add another third bracket '[]' and inside that, you should put your validators. Like Below:

this.yourForm= this.formBuilder.group({
    amount: [null, [Validators.required, Validators.min(1)]],
});


回答6:

Not directly related to the OP's question, but I got the same error on a slightly different problem. I had an async validator, but I forgot to return an Observable (or Promise) from it.

Here was my original async validator

public availableEmail(formControl: FormControl) {
   if(formControl && formControl.value){
     return this.http.get('')
   }
}

The thing is, what if the if-statement is false? We do not return anything, and we get a runtime error. I added the return type (making sure the IDE complains if we do not return the correct type), and then I return of(true) in the case the if-sentence failing.

Here is the updated async validator.

public availableEmail(formControl: FormControl): Observable<any> {
   if(formControl && formControl.value){
     return this.http.get('someUrl');
   }
   return of(true);
}


回答7:

Error: "cpf": ["", Validators.required, ValidateCpf]

Fix: "cpf": ["", [Validators.required, ValidateCpf]]