shamon shamsudeen
shamon shamsudeen

Reputation: 5858

Angular reactive form custom validation : update on change not working on first time

I have implemented a custom validation in my reactive form, basically, it will show an error when the length of the field reaches a certain limit.

this.formGroup = new FormBuilder().group({
     comment: [null, {
        validators: [ValidateCommentLength],
        updateOn: 'change'
      }]
  })

HTML

<textarea
            autocomplete="off"
            maxlength="3600"
            nxInput
            (ngModelChange)="valueChange($event)"
            type="text"
            [formControlName]="'comment'"
          ></textarea>
          <nx-error nxFormfieldError *ngIf="formGroup.get('comment').invalid" appearance="text">
            Maximum comment length is exceeded 
          </nx-error>
        </nx-formfield>

But the validation is not triggering on the first time of input change on the later changes it will work

UPDATE Validator

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

const MAX_LENGTH =  2;

    export function ValidateCommentLength(control: AbstractControl) {
    
        if (control.value) {
            if (!control.value.replace(/\s/g, '').length) {
                return null;
            }
            const  remaining = MAX_LENGTH - control.value.length;
            if (!remaining || Math.sign(remaining) === -1) {
                return { CommentError: true };
           }
    
        }
        return null;
    }

Upvotes: 3

Views: 3720

Answers (1)

Owen Kelvin
Owen Kelvin

Reputation: 15083

The problem

The problem is that nx-error will only show if the input is touched. But input is only touched when we blur out of the form

Solution

After the validator invalidates the input, trigger touched manually

export function ValidateCommentLength(control: AbstractControl) {
  if (control.value) {
    if (!control.value.replace(/\s/g, "").length) {
      return null;
    }
    const remaining = MAX_LENGTH - control.value.length;
    if (!remaining || Math.sign(remaining) === -1) {
      control.markAsTouched()
      return { CommentError: true };
    }
  }
  return null;
}

In the above I have just added control.markAsTouched() and now validation works as you expect

See Demo Here

Upvotes: 3

Related Questions