Reputation: 365
I am trying to create a validator for one of the fields in my form. This validator is created in a service, however, to create it I must make a get request that returns the value with which my validator must match, but since the server's response does not occur instantly when returning the value, it is always returned undefined. How can I stop the execution of the code until I get a response from the service?
constructor(private formBuilder: FormBuilder, private validators : ValidatorsService)
{
this.form = this.formBuilder.group({
max_range: [null, this.validators.getMaxRangeValidators()]
}
)
}
function in service ValidatorsService
public getMaxRangeValidators(): any[] {
let validators = [];
this.httpClient.get<Range>(this.url).suscribe(
(data)=>{
validators = [Validators.maxLength(data.maxLength)];
}
)
return validators;
}
Upvotes: 0
Views: 554
Reputation: 3727
You will need to implement async validator for your use case. Async validators lets you perform async operations (in your case, API calls).
An example, the below validator makes an API call to search for users and returns error if the user exists:
userValidator(): AsyncValidatorFn {
return (control: AbstractControl): Observable<{ [key: string]: any } | null> => {
return this.searchUser(control.value)
.pipe(
map(res => {
// if username is already taken
if (res.length) {
// return error
return { 'userNameExists': true };
}
})
);
};
For your use case:
public getMaxRangeValidators(): AsyncValidatorFn {
return (control: AbstractControl): Observable<{ [key: string]: any } | null> => {
return this.httpClient.get<Range>(this.url).pipe(map(res => {
if(control.value > res.maxLength) {
return {
'rangeError' : true,
'errorMessage': 'Length can't exceed ' + res.maxLength
}
}
}));
}
}
And then in your template you can check for rangeError
for the control and use the errorMessage property to display the error.
More details: https://angular.io/api/forms/AsyncValidator
Upvotes: 3