All I want to do is have the user type in a company name into an input box and it call a simple backend api to check if the company exists as they're typing it.
My API call works fine and returns "true" or "false" successfully as the user types in a value. It's just not displaying an error on the screen when it's false/company doesn't exist.
The part with "************" is where it's failing to return anything. No compile errors or runtime errors, just doesn't display a mat error when the company doesn't exist.
If you think this is an intimidating problem given the number of lines of code I don't blame you, I've been trying to figure out something seemingly simple that has taken nearly 6 hours.
my reports-view.component.ts file:
export class MyErrorStateMatcher implements ErrorStateMatcher {
isErrorState(
control: FormControl | null,
form: FormGroupDirective | NgForm | null
): boolean {
//console.log("blah");
const invalidCtrl = !!(control && control.invalid);
const invalidParent = !!(
control &&
control.parent &&
control.parent.invalid
);
return invalidCtrl || invalidParent;
}
}
@Component({
selector: 'app-reports-view',
templateUrl: './reports-view.component.html',
styleUrls: ['./reports-view.component.scss']
})
export class ReportsViewComponent implements OnInit {
matcher = new MyErrorStateMatcher();
CompanyNameInputForm: FormGroup;
companyNameValidator() {
return (form: FormGroup) => {
this.reportsPageService.doesCompanyNameExist(form.controls.companyName.value).subscribe((data) => {
console.log(data);
if (form.controls.companyName.value === "") {
console.log("returning null inside if");
return null;
}
else if (data==false) {
console.log("company name does not exist");
******************return { invalidCompanyName: true };******************
}
console.log("returning null at end");
return null;
});
}
}
ngOnInit() {
this.CompanyNameInputForm = this.formBuilder.group(
{
companyName: [""]
},
{ validator: this.companyNameValidator() }
);
this.CompanyNameInputForm.setValue({
companyName: this.companyName
});
}
constructor(private routingService: RoutingService, public reportsPageService: ReportsPageService,
private formBuilder: FormBuilder) {
this.BASE_URL = routingService.getBaseUrl();
}
}
in my service file:
doesCompanyNameExist(companyName: string):any {
return this.http.post(`${this.BASE_URL}/RESTAPI/reports/doesCompanyNameExist?companyName=${companyName}`,
this.httpOptions);
}
the html:
<form [formGroup]="CompanyNameInputForm">
<mat-form-field>
<input matInput placeholder="Company name" type="text" formControlName="companyName" [errorStateMatcher]="matcher">
<mat-error *ngIf="CompanyNameInputForm.hasError('invalidCompanyName')">Company does not exist
</mat-error>
</mat-form-field>
</form>
You are trying to validate the form group synchronously , while the validation results come after asynchronous check in your service.
You need to create an AsyncValidator and to update the configuration of the FormGroup .
This means you have to build the group like this:
this.CompanyNameInputForm = this.formBuilder.group(
{
companyName: [""],
},
{ asyncValidator: this.companyNameValidator }
);
Then you will need to update the validator method:
companyNameValidator(form: FormGroup): Observable<ValidationErrors | null> {
return this.reportsPageService.doesCompanyNameExist(form.controls.companyName.value)
.pipe(map((data) => {
console.log(data);
if (form.controls.companyName.value === "") {
console.log("returning null inside if");
return null;
}
else if (data == false) {
console.log("company name does not exist");
return { invalidCompanyName: true };
}
console.log("returning null at end");
return null;
}));
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.