Home > Enterprise >  Angular 14: Cannot read properties of undefined (reading 'controls')
Angular 14: Cannot read properties of undefined (reading 'controls')

Time:06-28

Need to compare two fields' values, validation is put into 2nd field's validation.

HTML:

    <form [formGroup]="fg">
        F1: <input type="text"  formControlName="f1" id="f1" (blur)="b($event)" .../>
        F2: <input type="text"  formControlName="f2" id="f2" .../>
    </form>

TS:

    import {  FormBuilder, FormGroup, FormControl, Validators } from '@angular/forms';
    export class c implements OnInit 
    {
        public fg!: FormGroup;   // another SO's accepted answer to tell ng not init yet.
        public b1: number = 0;
        
        constructor(private fb: FormBuilder)    // same error if "public" to "private", or moving content into ngOnInit()
        {
            this.fg = this.fb.group(
            {
                f1: ['', [Validators.required]] ,
                f2: ['', [Validators.required, this.compare1n2()]]
            }      
        );
        
        private compare1n2()
        {
            // runtime complains about this line, same for .get('f1')
            const v1 = this.fg.control['f1'].value; 
            
            return (control: FormControl) =>
            {
                const v2 = control.value || '';
                return (v1 != v2) ? {bad: 1} : null;  // workaround is to compare with b1.
            }
        }
        
        public b(e: any) {this.b1 = this.fg.controls['f1'].value; // ok too .get('f1').value
    }   

Everything works well except 1st line of compare1n2(). I've studied and used answers from post1, and post2.

Change this.fg = this.fb.group({...}) to below,

    this.fg = new FormGroup(
    {
        f1: new FormControl('', [Validators.required]) ,
        f2: new FormControl('', [Validators.required, this.compare1n2()])
    }   

still the same Cannot read properties of undefined (reading 'controls')

CodePudding user response:

Try this

 public fg: FormGroup = new this.fb.group( { f1: ['', [Validators.required]] , f2: ['', [Validators.required, this.compare1n2()]] }

CodePudding user response:

Put that line inside the callback function and check if f1 has actually been initialized before using it.

  private compare1n2() {
    return (control: FormControl) => {
      if (!this.fg?.controls || !this.fg.controls['f1']) return null;
      const v1 = this.fg.controls['f1'].value;
      const v2 = control.value || '';
      return v1 != v2 ? { bad: 1 } : null;
    };
  }

It seems that the validators are called once during initialization.

CodePudding user response:

I wonder if you have any compilation error on this line of the code :

const v1 = this.fg.control['f1'].value; 

I don't think fg would have a property/method name as 'control'. It should be 'controls' ( plural) same as you used in first line of methond 'b'.

Please review.

  • Related