1

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.

Sylvain C.
  • 1,043
  • 1
  • 11
  • 27

3 Answers3

0

may be you need to check that property :

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

 ngOnChanges(changes: SimpleChanges): void {
    if(changes['cruiseArray']) {
        this.checkDuplicates(group: FormGroup)
    }
  }
Chady BAGHDADI
  • 203
  • 2
  • 7
0

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();
    }
}
An Nguyen
  • 96
  • 1
  • 2
  • 6
0

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]
Mr. Stash
  • 2,940
  • 3
  • 10
  • 24