Comparing values in Custom Validator in Angular

Viewed 1243

I'm trying to compare two input values in a custom validator. There should be an error if the minValue is greater than the maxValue.

FormGroup:

    sumFormGroup = this.formBuilder.group({
     from: ['', [Validators.min(0), sumValidator]],
     to: ['', [Validators.min(0), sumValidator]]
  });

custom validator:

 function sumValidator (control: AbstractControl):{[key: string]: boolean} | null {
   let minValue = control.get(this.sumFormGroup.get('from')).value;
   let maxValue = control.get(this.sumFormGroup.get('to')).value;
   if(minValue != maxValue){
    return {'ageValidator': true}
  }
  return null;
};

Error in browser console:

ERROR TypeError: Cannot read property 'sumFormGroup' of undefined
    at sumValidator in bla.ts
    (...)

Can anyone help? Thank you

1 Answers

Making the validation 'more' pure would help. Also I would suggest making two validations for this one.

function smallerThan(otherControlName: string) {
    return (control: AbstractControl): { [key: string]: boolean } | null => {
        if (!control.parent) {
            return null; // Control is not yet associated with a parent.
        }
        const thisValue = control.value;
        const otherValue = control.parent.get(otherControlName).value;
        if (thisValue < otherValue) {
            return null;
        }

        return {
            'smallerthan': true
        }
    };
}

function greaterThan(otherControlName: string) {
    return (control: AbstractControl): { [key: string]: boolean } | null => {
        if (!control.parent) {
            return null; // Control is not yet associated with a parent.
        }
        const thisValue = control.value;
        const otherValue = control.parent.get(otherControlName).value;
        if (thisValue > otherValue) {
            return null;
        }

        return {
            'greaterthan': true
        }
    };
}

Usage:

sumFormGroup = this.formBuilder.group({
    from: ['', [Validators.min(0), smallerThan('to')]],
    to: ['', [Validators.min(0), greaterThan('from')]]
 });

Perhaps you also need to take into account that the values may not be equal, but you could easily create two more validators called smallerThanOrEquals and greaterThanOrEquals.

If you wish to sync the validations, you could try to do it in the following way in your component:

ngOnInit() {
    // Example in the init, but make sure this.sumFormGroup is already created. 
    this.sumFormGroup.get('from').valueChanges.subscribe(() => this.sumFormGroup.get('to').updateValueAndValidity({ onlySelf: true, emitEvent: false }));
    this.sumFormGroup.get('to').valueChanges.subscribe(() => this.sumFormGroup.get('from').updateValueAndValidity({ onlySelf: true, emitEvent: false }));
}
Related