Oczekiwany walidator zwróci Promise lub Observable

112

Próbuję przeprowadzić niestandardową weryfikację w Angular 5, ale mam następujący błąd

Expected validator to return Promise or Observable

Chcę tylko zwrócić błąd do formularza, jeśli wartość nie pasuje do wymaganego, oto mój kod:

To jest komponent, w którym jest moja 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]
    })     
   }

Ten kod znajduje się w pliku z walidacją, którą chcę zaimplementować:

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

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

Czy ktoś może mi pomóc? Czy ten rodzaj walidacji działa tylko z obserwowalnymi, czy mogę to zrobić bez obietnicy lub obserwowalności? dzięki

Renê Silva Lima
źródło

Odpowiedzi:

331

Oznacza to, że musisz dodać wiele walidatorów w tablicy

. Przykład:

Z błędem

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

Powyżej jeden zgłasza błąd, który walidator zwraca Promise lub Observable

Naprawić:

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

Wyjaśnienie:

W kątowej walidacji w formie reaktywnej przeprowadzana za pomocą wbudowanych walidatorów, które mogą być podane w tablicy w drugiej pozycji, gdy używa się wielu walidatorów .

FIELD_KEY: [INITIAL_VALUE, [LIST_OF_VALIDATORS]]

Vimalraj
źródło
1
Co ciekawe, całkowicie przegapiłem nawiasy wokół walidatorów z zaakceptowanej / popularnej odpowiedzi. Dobrze poradziłeś sobie ze wskazaniem problemu i rozwiązania.
CPHPython
Twój pierwszy punkt to poprawna odpowiedź. Ta odpowiedź powinna być zaznaczona jako prawidłowa.
Valentino Pereira
1
wstyd dla kanciastych facetów! problem nie jest w ogóle widoczny, jest to składnia tablicy
happyZZR1400
42

Powinno działać:

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

argumenty, których oczekuje formant formularza, są następujące:

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

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

Deblaton Jean-Philippe
źródło
2

Nie jest to bezpośrednio związane z pytaniem OP, ale otrzymałem ten sam błąd przy nieco innym problemie. Miałem walidator asynchroniczny, ale zapomniałem zwrócić z niego Observable (lub Promise).

Oto mój oryginalny walidator asynchroniczny

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

Rzecz w tym, co się stanie, jeśli instrukcja-if jest fałszywa? Nic nie zwracamy i otrzymujemy błąd wykonania. Dodałem typ zwrotu (upewniając się, że IDE narzeka, jeśli nie zwrócimy prawidłowego typu), a następnie zwracam of(true)w przypadku niepowodzenia zdania if.

Oto zaktualizowany walidator asynchroniczny.

public availableEmail(formControl: FormControl): Observable<any> {
   if(formControl && formControl.value){
     return this.http.get('someUrl');
   }
   return of(true);
}
Jan
źródło
1

Validators.compose () jest zbędne;

Możesz po prostu przekazać tablicę. Problem OP jest spowodowany niepowodzeniem zawijania walidatorów w [], aby uczynić je tablicą, dlatego zakłada się, że minLength () jest asynchroniczna, a wynikowy komunikat o błędzie.

Mam nadzieję, że to rozwiązanie Ci pomoże. Dzięki.

Kamlesh
źródło
Tak. Użyłem Validators.compose ([]). zadziałało dla mnie
Kumaresan Perumal
1

błąd: nazwa_użytkownika: ['', [Validators.required, Validators.minLength (3)], forbiddenNameValidator (/ hasło /)],

ans: nazwa_użytkownika: ['', [Validators.required, Validators.minLength (3), forbiddenNameValidator (/ hasło /)]],

walidatory używają tylko drugiego parametru w tablicy wewnętrznej. nie dla tablicy zewnętrznej

KL Sathish
źródło
„To może nie dać odpowiedzi na pytanie. Dodaj właściwe wyjaśnienie. Gdy zdobędziesz wystarczającą reputację, będziesz mógł komentować każdy post; zamiast tego udziel odpowiedzi, które nie wymagają wyjaśnień od pytającego ”.
Pushkr
1

Jeśli dodajesz wiele walidatorów, musisz dodać kolejny trzeci nawias „[]”, a wewnątrz niego umieść swoje walidatory. Jak poniżej:

this.yourForm= this.formBuilder.group({
    amount: [null, [Validators.required, Validators.min(1)]],
});
Abdus Salam Azad
źródło
1

Błąd: "cpf": ["", Validators.required, ValidateCpf]

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

Achraf Farouky
źródło
0

Myślę, że dobrze jest wyjaśnić oprócz zaakceptowanej odpowiedzi, że błąd występuje, ponieważ podczas korzystania z formularzy reaktywnych do tworzenia FormControl, po wartości początkowej następujące argumenty są odpowiednio walidatorami synchronicznymi i walidatorami asynchronicznymi zgrupowanymi w postaci tablicy każdy . Na przykład:

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

Jeśli formant ma tylko jeden z nich, Angular akceptuje go jako pojedynczy element. Na przykład:

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

Dlatego zapominając o nawiasach do ich grupowania, Angular zakłada, że ​​druga pozycja walidatora jest częścią walidatorów Async, więc otrzymujemy Expected validator to return Promise or Observable

Laszlo Sarvold
źródło