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)
}
}