I want to make custom validator which would make submit button available only if text in form is unique. I have VulnarabilitiesClass instance, which contains an array of objects with id and name fields. After typing any text in my form I get this error: Error: undefined is not an object (evaluating 'this.systemVulnarabilities')
<form [formGroup]="profileForm">
<label>
Vulnarability Name:
<input type="text" formControlName="name" required>
</label>
</form>
<p>
Form Status: {{ profileForm.status }}
</p>
<form [formGroup]="profileForm" (ngSubmit)="onSubmit()">
<button type="submit" [disabled]="!profileForm.valid">Submit</button>
this.systemVulnarabilities = new VulnarabilitiesClass();
profileForm = this.fb.group({
name: ['', Validators.required,this.UniqueNameValidator],
});
private UniqueNameValidator(control: FormControl): ValidationErrors{
let vulnarabilityName: string = control.value;
console.log(vulnarabilityName);
console.log(this.systemVulnarabilities.displayList.toString());//no output already
let found: number = this.systemVulnarabilities.displayList.map(function(e) { return e.name; }).indexOf(vulnarabilityName); //mistake
if(found === -1){
return {invalidPassword: 'this name already exists'};
}
return null;
}
This error happens because UniqueNameValidator
method is executed with different from component context this
. The reason for this is that in javascript context this
depends on how the function is executed and not where it was declared.
The simple fix is to use Function.prototype.bind method that makes sure correct context this
this.UniqueNameValidator.bind(this)
Also, if your validator is synchronous then you need to wrap your validators in array otherwise Angular will treat it as asynchronous validator:
name: ['', [Validators.required, this.UniqueNameValidator.bind(this)]],