2

I made a stackblitz with my issue I used templating to show the errors, when I do form.errors it returns null even though form.get('oldPassword').errors isn't returning null

EDIT
as a bonus I'm getting errors when I'm defining a getter for each field

get oldPassword() {
   return this.form.get('oldPassword')
}

EDIT

Here is my code working

4 Answers 4

2

Check this feature request here: https://github.com/angular/angular/issues/10530

The FormGroup errors object will be not null, only when a FormGroup validator returns an error and not for control validators.

Consider a scenario where both values are ok but their combination is not. That's where the FormGroup validator could return something like PasswordAndVerificationAreNotEqual.

Check Get all validation errors from Angular 2 FormGroup to get all form group errors solution.

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

Comments

1

Angular doesn't expose control errors to FormGroup https://github.com/angular/angular/issues/10530 But it does handle invalid state for FormGroup.

In order to recursively get all errors I would offer you using some function like:

export function collectErrors(control: any): any | null {
  if (control.controls) {
    return Object.entries(control.controls).reduce(
      (acc, [key, childControl]) => {
        const childErrors = collectErrors(childControl);
        if (childErrors) {
          acc = { [key]: childErrors, ...acc };
        }
        return acc;
      },
      null
    );
  } else {
    return control.errors;
  }
}

then you can use it as follows:

onClick() {
  console.log(collectErrors(this.form));
  console.log(this.form.get("oldPassword").errors);
}

Stackblitz Example

3 Comments

Lots of great answers, however this one gave me the idea to use the invalid state to disable the submit button which is what I wanted to do orignally
way to complicated => Angular doesn't expose control errors to FormGroup of course it does
@Nickolaus then why is there an open issue that says it doesn't? At least not in an easy to access fashion. - github.com/angular/angular/issues/10530 What is your simpler solution to access all errors for all controls within a form?
1

for sure i am with nickolaus you should use observables it is much better if you cant refactor your app then use this

in html

<div *ngFor="let obj of getErrorList(form.controls)">
      <p>FormGroup errors: {{ obj | json }}</p>
    </div>

in ts

getErrorList(errorObject) {
  let errors = [] ;
  for(let key in errorObject){
    let obj={
      name:key,
      errors:errorObject[key].errors
    }
    errors.push(obj);
  }
  console.log(errors);
  return errors;
}

1 Comment

This is for a class, observables are later in the syllabus, we are learning the basics now. however good to know
1

You problem is the setTimeout in the validator:

    static passwordValidator(control: AbstractControl): Promise<ValidationErrors | null> {

        return new Promise((resolve, reject) => {
        ==>    setTimeout(() => {
                if (control.value === "1234") {
                    resolve({ passwordValidator: true })
                }
                resolve(null)
            }, 2000);
        });


    }

setTimeout bypasses Angulars ChangeDetection, therefore the view is not informed about the validation error.

Therefore you should always use Observables in angular there is hardly a case where you need promises... and by using an observalbe you could delay the detection by piping the timeout and the form validation should work properly

Update: Your password validator should look like this:

export class CustomValidators {
    static passwordValidator(control: AbstractControl): Observable<ValidationErrors | null> {
        return of(control.value)
          .pipe(
            debounceTime(2000),
            distinctUntilChanged(),
            map(currentValue => currentValue === "1234" ? { passwordValidator: true } : null )
          )
    }
}

https://stackblitz.com/edit/angular-1su3cm

2 Comments

That makes sense however, I just removed the async validator and the form.errors is still returning null while the forms.get('oldPassword'). errors is returning an object, when they should be the same; why?
@RaphaelCastro *ngIf="form.get('oldPassword').errors && ..." must be *ngIf="form.get('oldPassword').errors.length > 0 && ..."

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.