Validador esperado para devolver Promise u Observable

104

Estoy tratando de hacer una validación personalizada en Angular 5 pero me enfrento al siguiente error

Expected validator to return Promise or Observable

Solo quiero devolver un error al formulario si el valor no coincide con el requerido, aquí está mi código:

Este es el componente donde esta mi forma

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

Este código está en el archivo con la validación que quiero implementar:

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

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

¿Alguien me puede ayudar? ¿Ese tipo de validación solo funciona con observables o puedo hacerlo sin ser una promesa u observable? Gracias

Renê Silva Lima
fuente

Respuestas:

309

Significa que debe agregar varios validadores en una matriz

. Ejemplo:

Con error

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

Por encima de uno arroja un error de que el validador devuelva Promesa u Observable

Reparar:

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

Explicación:

En la validación de forma reactiva angular realizada mediante el uso de validadores incorporados que se pueden proporcionar en una matriz en la segunda posición, cuando se utilizan varios validadores .

FIELD_KEY: [INITIAL_VALUE, [LIST_OF_VALIDATORS]]

Vimalraj
fuente
1
Curiosamente, me perdí por completo los corchetes alrededor de los validadores de la respuesta aceptada / popular. Hizo bien en señalar tanto el problema como la solución.
CPHPython
Su primer punto es la respuesta correcta. Esta respuesta debe marcarse correctamente.
Valentino Pereira
1
IMPRESIONANTES MUCHAS GRACIAS
Ravi Rajput
1
¡Qué vergüenza los chicos angulosos! el problema no es observable en absoluto, es una sintaxis de matriz
happyZZR1400
42

Lo siguiente debería funcionar:

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

los argumentos que espera el control de formulario son los siguientes:

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

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

Deblaton Jean-Philippe
fuente
2

No está directamente relacionado con la pregunta del OP, pero obtuve el mismo error en un problema ligeramente diferente. Tenía un validador asíncrono, pero olvidé devolver un Observable (o Promesa) de él.

Aquí estaba mi validador asíncrono original

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

La cuestión es, ¿qué pasa si la declaración if es falsa? No devolvemos nada y obtenemos un error de tiempo de ejecución. Agregué el tipo de retorno (asegurándome de que el IDE se queje si no devolvemos el tipo correcto), y luego lo devuelvo of(true)en caso de que falle la sentencia if.

Aquí está el validador asíncrono actualizado.

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

Validators.compose () es redundante;

Puede simplemente pasar una matriz. El problema de OP es causado por no envolver los validadores en [] para convertirlos en una matriz, por lo tanto, se asume que minLength () es asíncrono y el mensaje de error resultante.

Espero que esta solución te ayude. Gracias.

Kamlesh
fuente
Si. Usé Validators.compose ([]). funcionó para mí
Kumaresan Perumal
1

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

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

los validadores usan solo el segundo parámetro en la matriz interna. no para matriz exterior

KL Sathish
fuente
“Esto puede no dar respuesta a la pregunta. Agregue una explicación adecuada. Una vez que tenga suficiente reputación, podrá comentar en cualquier publicación; en su lugar, proporcione respuestas que no requieran aclaración por parte del autor de la pregunta ".
Pushkr
1

Si agrega múltiples validadores, entonces necesita agregar otro tercer corchete '[]' y dentro de eso, debe poner sus validadores. Como abajo:

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

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

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

Achraf Farouky
fuente
0

Creo que es bueno aclarar además de la respuesta aceptada que el error ocurre porque cuando se usan formas reactivas para crear un FormControl, después del valor_inicial los siguientes argumentos son, respectivamente, validadores síncronos y validadores asíncronos agrupados en forma de matriz cada uno . P.ej:

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

Si el control tiene solo uno de ambos, Angular lo acepta como un solo elemento. P.ej:

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

Por lo tanto, al olvidarse de los corchetes para agruparlos, Angular asume que el segundo elemento del validador es parte de los validadores Async y así obtenemos el Expected validator to return Promise or Observable

Laszlo Sarvold
fuente