Currently, I am exploring Angular reactive forms validation and facing an issue with implementing Google autocomplete in an input field:
<input autocorrect="off" autocapitalize="off" spellcheck="off" type="text" class="input-auto input" formControlName="address">
The autocomplete feature suggests places as you type a keyword:
https://i.stack.imgur.com/ASr7n.png
I want to validate the address by ensuring it includes a zip code. Only addresses with a zip code should be considered valid. When a suggestion is chosen, the validation should occur based on whether the selected address contains a zip code.
The address information from Google Places API populates global variables (zipCode
, countryName
, cityName
, streetName
) in one form control for the entire address:
this.mapsAPILoader.load().then(() => {
const autocomplete = new window['google'].maps.places.Autocomplete(this.searchElementToRef.nativeElement, {
types: ['address']
});
autocomplete.addListener('place_changed', () => {
this.ngZone.run(() => {
const place = autocomplete.getPlace();
if (place.geometry === undefined || place.geometry === null) {
return;
}
this.form.get('address').setValue(place.formatted_address);
for (const addressComponent of place.address_components) {
for (const addressComponentType of addressComponent.types) {
switch (addressComponentType) {
case 'postal_code':
this.zipCode = addressComponent.long_name;
break;
case 'country':
this.countryName = addressComponent.long_name;
break;
case 'locality':
this.cityName = addressComponent.long_name;
break;
case 'route':
this.streetName = addressComponent.long_name;
break;
}
}
}
});
});
});
In the method that creates the form using FormBuilder
, a custom validator is used:
public createFormGroup(): FormGroup {
return this.fb.group({
address: [null, this.zipCodeValidator()]
});
}
The zipCodeValidator()
custom validation method is expected to trigger an error when the address lacks a zipCode
:
public zipCodeValidator(): ValidatorFn {
return (control: AbstractControl): Observable<{ [key: string]: boolean } | null> => {
if (this.zipCode !== undefined) {
return of({ zipCode: true });
}
return null;
};
}
However, regardless of whether a zip code is present, the validation always passes as valid:
https://i.stack.imgur.com/7evlc.png
When using the form control's value as a condition, the validation works correctly. Modifying the validation method as shown below triggers an error when no input is provided:
public zipCodeValidator(): ValidatorFn {
return (control: AbstractControl): Observable<{ [key: string]: boolean } | null> => {
if (control.value === null) {
return of({ noValue: true });
}
return null;
};
}
Question:
Is it feasible to validate the form under these conditions, considering that the zipCode
value is not directly passed to any form control?