Expected validator to return Promise or Observable

JavascriptAngularAngular5Angular FormsAngular Validation

Javascript Problem Overview


I'm 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 doesn't match the required, here's my code:

This is the component where my form is

  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;
}

Does that type of validation only work with observables or can I do it without being a promise or observable?

Javascript Solutions


Solution 1 - Javascript

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]]

Solution 2 - Javascript

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

Solution 3 - Javascript

I think it is good to clarify in addition to the accepted answer that the error happens because when using reactive forms for creating a FormControl, after the initial_value the following arguments are, respectively, synchronous validators and async validators grouped in the form of an array each. E.g:

myFormGroup = this.fb.group({
    myControl: ['', [ mySyncValidators ], [ myAsyncValidators ] ]
})

If the control happens to have just one of either, Angular accepts it as a single element. E.g.:

myFormGroup = this.fb.group({
    myControl: ['', mySyncValidator, myAsyncValidator ]
})

Therefore, when forgetting about the brackets for grouping them Angular assumes the second validator item is part of the Async validators and so we get the Expected validator to return Promise or Observable

Solution 4 - Javascript

This type of error usually occurs if u do something like this -

name: ['',Validators.required, Validators.compose([Validators.minLength(3),Validators.maxLength(15)])]

Change this to -

name: ['', Validators.compose([Validators.required,Validators.minLength(3),Validators.maxLength(15)])]

2nd field -> validators

Solution 5 - Javascript

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

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

Solution 6 - Javascript

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)]],
});

Solution 7 - Javascript

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);
}

Solution 8 - Javascript

You surely defined multiple validators in your reactive form.

wrong :

'status': [false,,[Validators.required]]

I just used two commas (,) after defining the value of status false.

Right :

 'status': [false,[Validators.required]]

Solution 9 - Javascript

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.

Solution 10 - Javascript

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRen&#234; Silva LimaView Question on Stackoverflow
Solution 1 - JavascriptVimalrajView Answer on Stackoverflow
Solution 2 - JavascriptDeblaton Jean-PhilippeView Answer on Stackoverflow
Solution 3 - JavascriptLaszlo SarvoldView Answer on Stackoverflow
Solution 4 - Javascriptrohit.khurmi095View Answer on Stackoverflow
Solution 5 - JavascriptAchraf FaroukyView Answer on Stackoverflow
Solution 6 - JavascriptAbdus Salam AzadView Answer on Stackoverflow
Solution 7 - JavascriptJohnView Answer on Stackoverflow
Solution 8 - Javascriptnagender pratap chauhanView Answer on Stackoverflow
Solution 9 - JavascriptKamleshView Answer on Stackoverflow
Solution 10 - JavascriptK.L SathishView Answer on Stackoverflow