Home > Software engineering >  Input property is undefined in custom validator function - Angular
Input property is undefined in custom validator function - Angular

Time:11-26

I have the following form with custom validators:

this.Form = this.fb.group({
      cruiseId: new FormControl(this.leg.cruiseId),
      startDate: new FormControl(this.leg.startDate, [Validators.required]),
      endDate: new FormControl(this.leg.endDate)
    }, { validators: [this.checkDuplicates, this.checkDates] });

In my component, I have an input property which contains all departure dates for a cruise (@Input() cruiseArray!: cruiseItem[];). Using the checkDuplicates function, I want to verify that we don't have 2 identical departure dates for the same cruise.

checkDuplicates(group: FormGroup) {   
    console.log(this.cruiseArray);
    let sDate = group.get('startDate')?.value;
    if (sDate !== null && this.cruiseArray.find(x => x.startDate === sDate))
    {
      return { invalidDuplicate: true }
    }       
    return null;
  }

My concern is that this.cruiseArray is alway undefined. If I try the following in my component

ngOnInit(): void {
    console.log(this.cruiseArray);
  }

it works perfectly and my array returned by the parent is populated.

Full code:

  @Component({
      selector: ..,
      templateUrl: ..,
      styleUrls: [..]
    })
    export class MyComponent implements OnInit {
      Input() cruiseArray!: cruiseItem[];
    
    ....
    ngOnInit(): void {
            console.log(this.cruiseArray); <--- DOES WORK
          }
    ....
ngOnChanges(changes: SimpleChanges) {       
    this.createForm();
  }
    ....
      createForm() {
        this.Form = this.fb.group({
              cruiseId: new FormControl(this.leg.cruiseId),
              startDate: new FormControl(this.leg.startDate, [Validators.required]),
              endDate: new FormControl(this.leg.endDate)
            }, { validators: [this.checkDuplicates, this.checkDates] });
      }
    
    ....
    
      checkDuplicates(group: FormGroup) {   
            console.log(this.cruiseArray); <--- DOES NOT WORK
            let sDate = group.get('startDate')?.value;
            if (sDate !== null && this.cruiseArray.find(x => x.startDate === sDate))
            {
              return { invalidDuplicate: true }
            }       
            return null;
          }
      }
    }

Why this.cruiseArray is undefined in my validator function even when it is populated elsewhere in my component.

CodePudding user response:

The validator function is inside the class, 'this' keyword inside the validator does not point to the class object, so binding the class object with the method should solve the problem

validators: [this.checkDuplicates.bind(this), this.checkDates]

CodePudding user response:

Use changeDetection: ChangeDetectionStrategy.OnPush (more info here), or assign cruiseArray = [...] in parents component. If you use cruiseArray.push() or cruiseArray.pop() in parents component, it won't trigger ngOnChanges (same issue here).

Moreover, if you have multiple Input(), you should call this.createForm() with condition:

ngOnChanges(changes: SimpleChanges) {
    if (changes['cruiseArray']) {
        this.createForm();
    }
}

CodePudding user response:

may be you need to check that property :

 @Input() cruiseArray: !: cruiseItem[];

 ngOnChanges(changes: SimpleChanges): void {
    if(changes['cruiseArray']) {
        this.checkDuplicates(group: FormGroup)
    }
  }
  • Related