2

I have a number of custom validators that will apply to fields in a dynamically generated Reactive Form in Angular 7.

The template looks like this:

<ng-container class="table-wrapper" *ngIf="!field.hide && field.display === fieldTypes.get('Text')">
  <label>
    <span class="form-label">{{field.label}}</span>
    <span *ngIf="dynForm.controls[field.name].invalid
    && ( dynForm.controls[field.name].dirty || dynForm.controls[field.name].touched )">
      {{errorMessageResolver(field, dynForm.controls[field.name].errors)}}
    </span>
  </label>
  <input type="text" name="{{field.name}}" value="{{field.val}}" formControlName="{{field.name}}"/>
</ng-container>

As you can see, I have a function that pulls out the generated ValidationError from the form and feeds it into the following function:

  errorMessageResolver(field: Field, errors: ValidationErrors) {
    console.log('valids=' + field.validations.length);
    console.log(errors);
    console.log(errors as ValidationErrors);
    console.log(errors.hasOwnProperty('required'));
    console.log(errors.hasOwnProperty('minLength'));
    console.log(errors.minLength);
    console.log(errors.hasOwnProperty('maxLength'));
  }

The result of the extensive console logging is: enter image description here

As I hope you can see, the minLength ValidationError is definitely being picked up, because you can see the console output:

{ minLength: {...}}

But the following attempted consoles should show how there doesn't seem to be a way to get hold of the actual value. So how do you get hold of the key and its value?

Community
  • 1
  • 1
Michael Coxon
  • 3,337
  • 8
  • 46
  • 68
  • It's minlength with lowercase L. I hope that's not what's confusing you. – Anjil Dhamala Mar 23 '19 at 02:56
  • you can use 'errorMessage' property in the html form, refer this link https://stackoverflow.com/questions/53920271/what-is-the-best-practice-to-show-reactive-form-error-message-without-multiple – Ami Vyas Mar 23 '19 at 03:16

1 Answers1

3

Unfortunately Angular Forms do not provide validation messages/values. They are very simple objects that simply display the name of each Validator attached to the FormControl whose requirements the <input> does not meet.

So when the minLength error exists, that means that the validator returned invalid, otherwise you will not see minLength in the errors object at all.

In your example you provide the <input> element with a formControlName of field.name. You should be able to access the errors via this FormControl's errors property in your method like:

if(errors['required']) {
    // The required validator returned invalid
}

Or by using the hasError method on the FormControl like so:

if(this.form.get(field.name).hasError('required')) {
    // The required validator returned invalid
}

Just to make you aware, the reason errors.minLength returns undefined is because the error object is a type that looks like this: { [key: string]: any; } i.e. it is an indexable type. The property accessor fails because it really doesn't have a property called minLength.

Darren Ruane
  • 2,385
  • 1
  • 8
  • 17
  • Thanks for your answer: even getting hold of the name would be ok actually, because I could use it to then return my error messages. Other than JSON.stringify(), nothing seems to work to even get the key: "minLength" – Michael Coxon Mar 23 '19 at 02:43
  • Understood, please see my edit for more details. Hopefully it helps. – Darren Ruane Mar 23 '19 at 02:53