In the parent component I define the form.
cartForm = new FormGroup({
company: new FormControl('', [Validators.required]),
costCenter: new FormGroup({
account: new FormControl('', [Validators.required]),
activity: new FormControl('', [Validators.required, Validators.maxLength(5), Validators.minLength(5)]),
project: new FormControl('', [Validators.required, Validators.minLength(3), Validators.maxLength(10)]),
})
});
then the formControl project
is used in a child component. In this component I need a custom validation and I can achive that by just adding
validate(control: AbstractControl): ValidationErrors | null {
// To my validation here
}
And that works except that the Validators
specified in the parent componet are overwritten.
Second approach would be to create a custom validator class.. but then I can't get the @Input from the component..?
Update: This is the component
@Component({
selector: 'ssp-project',
templateUrl: './project.component.html',
styleUrls: ['./project.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ProjectComponent implements ControlValueAccessor, OnInit {
@Input('companyNumber') set companyNumber(companyNumber: string) {
this._companyNumber = companyNumber;
}
private _companyNumber: string;
constructor(
@Optional() @Self() public ngControl: NgControl,
) {
if (this.ngControl != null) {
// Setting the value accessor directly (instead of using the providers) to avoid running into a circular import.
this.ngControl.valueAccessor = this;
}
}
onTouched = (_value?: any) => { };
onChanged = (_value?: any) => { };
writeValue(val: string): void {
if (val) {
this.ngControl.control?.setValue(val);
}
}
registerOnChange(fn: any): void {
this.onChanged = fn;
}
registerOnTouched(fn: any): void {
this.onTouched = fn;
}
registerOnValidatorChange(fn: any): void {
this.onChanged = fn;
}
ngOnInit() {
// this.ngControl.control.setValidators([this.validate.bind(this)]);
this.ngControl.control.setValidators(this.ngControl.control.validator ? [this.ngControl.control.validator, this.validate] : this.validate);
this.ngControl.control.updateValueAndValidity();
}
validate(control: AbstractControl): ValidationErrors | null {
if (this._companyNumber && control.value) {
return this._costCenterService
.validateProject(control.value, this._companyNumber)
.pipe(
debounceTime(3000),
map(projectIsValid => {
return { invalid: !projectIsValid };
})
).subscribe();
}
}
}
You can add a validator to the list of existing validators using the
validator
property of the FormControlEdit: since the code was added in the question, the focus has shifted to async validators. E.g.: