angularangular-formscustom-validators

Angular Forms reactive - cross-control validation


I'm working on a validator for a reactive form in angular 5, and having difficulty setting a validator that is based on the value of another input.

The form looks something like this:

let myRules = new FormArray([]);
myRules.push(this.newRuleFormGroup(1, 'period', 1));

this.myForm = new FormGroup({
      'name': new FormControl(name, [Validators.required, this.validate_usedName.bind(this)]), // V: must not exist already
      'icon': new FormControl(icon, [Validators.required]), // has default
      'rules': myRules
    })

'rules' is a FormArray, and I push new FormGroups from the template using:

newRuleFormGroup = (amount: number, period: string, repAmount: number = 1) => {
    return new FormGroup({
      'amount': new FormControl(amount, [Validators.required]),
      'type': new FormControl(period, [Validators.required]),
      'repAmount': new FormControl(repAmount, [this.validate_repAmount.bind(this)])
    })
  }

repAmount is only required when type == "period". In the validator for repAmount, I am trying to reach the parent FormGroup and try to get the value of his child 'type' control. Something like this:

validate_repAmount(control:FormControl): {[s:string]: boolean}{
  let type = control.parent.get('type');// Cannot read property 'get' of undefined
  let controlValue = control.value;
  console.log(control.parent); // returns the parent FormGroup object
  if(type.value == 'period' && (controlValue != '' || controlValue>0)) {
      return {'repAmountMissing':true};
  }
    return null;
  }

But I keep getting an error saying Cannot read property 'get' of undefined. If I try to console.log(control.parent), i get the FormGroup object as expected, but I can't seem to access it in any way using its properties.

Could anyone suggest a way to access the 'type' value in the same group for the validator?


Solution

  • You should wrap your code as below:

    if (parent) { YOUR_VALIDATION_GOES_HERE }
    

    I had the same issue once and this is how I solved it.

    Update: You can try something like this.

    validate_repAmount(control: FormControl): { [s: string]: boolean } {
    const parent = control.parent;
    if (parent) {
        let type = parent.get('type');
        let controlValue = control.value;
        if (type.value == 'period' && (controlValue != '' || controlValue > 0)) {
            return { 'repAmountMissing': true };
        }
    }
    
    return null;
    }