2

Is there anyway to Call method automatically like checkValidity() to set { 'invalid': false/true } after async form validation (i.e i have this.uniqueNameValidator.bind(this)) async call)

Checked https://stackoverflow.com/a/49520534/1225526 but it looks like submit method call after submit click action

Tried Form.valueChanges not work as expected it is called before validation

this.editForm.valueChanges
            .pipe(takeUntil(this._onDestroy))
            .subscribe(changes => {
                if (changes) {
                    this.onChange(Object.assign({userId: this.userId}, changes));
                }
                this.checkValidity(); <-- This part is not working as expected it is called before validation
            });



checkValidity() {
        if (((this.editForm.controls.userName.pristine && this.editForm.controls.userName.pending) ||
            !this.editForm.controls.userName.invalid)
            && !this.editForm.controls.password.invalid) {
            this.editForm.setErrors({ 'invalid': false });
        } else {
            this.editForm.setErrors({ 'invalid': true });
        }
    }

this.editForm = new FormGroup({
              userDisplayName: new FormControl({ value: '', disabled: true }),
              userName: new FormControl('', [ Validators.required], 
                       this.uniqueNameValidator.bind(this)), <-- async Validation
              password: new FormControl('',[Validators.required,
                       validateUserPassword()])});


uniqueNameValidator(control: AbstractControl) {
        return control.valueChanges.pipe(
            switchMap(() => this.service.checkUsernameAvailability(control.value)),
            take(1),
            map(({data}) => {
                control.markAsTouched();
                this.componentChangeDetector.markForCheck();
                return data.checkUsernameAvailability ? null : {invalid: false};
            }), catchError((error): any => {
                return of(null);
            }));
    }

Any help would be great.

3
  • you can do that at your async validator function. add a tap() to your pie and set parent form error sth like this : tap(()=>control.parent.setErrors({'invalid':true}))... Commented Nov 12, 2019 at 9:25
  • I have a query. Why would you set your editForm errors. If any of the validation fails, editForm.valid returns true or false. Why would you explicitly call checkValidity and do so? Commented Nov 12, 2019 at 9:27
  • I am using ControlValueAccessor as child form for writing other business data + form data which is instance of FormArray I need this child form to be validated manually since i am passing those FormControl to this child component for setting validation check so that i can iterate through this formArray from parent and enable submit button after checking their validity. Part of that form field is prefilled so it remains pending. Commented Nov 12, 2019 at 9:35

1 Answer 1

3

AbstractControl provides two Observables valueChanges and statusChanges, maybe those can help you.

Sign up to request clarification or add additional context in comments.

1 Comment

I used form statusChanges with setTimeout it worked. this.editForm.statusChanges.pipe(takeUntil(this._onDestroy)) .subscribe(status => this.checkValidity());

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.