DEV Community

Cover image for Using Google Place to build a country autocomplete
Agustin Maggi
Agustin Maggi

Posted on

Using Google Place to build a country autocomplete

Google Places API is a service that provides information about places and addresses. This functionality is very useful for applications requiring specific location input from users.

One missing feature in the Google Places API is the ability to search for countries. In this tutorial, we will see how to implement a country autocomplete feature using the Google Places API and the React Select library.

You can see the final result at country-autocomplete.vercel.app.

Prerequisites

Getting Started

We will begin with our class that will handle the Google Places API. This class will have all the methods that we will need to interface with the API and ultimately generate the countries list for our autocomplete dropdown.

The first method is the SearchCountry. This will receive a search string and return a list of countries matching that value. We are using the AutocompleteService from the Google Places API to get the list of matches. We limit results to 'regions' to exclude streets or cities.

SearchCountry(search: string): Promise<google.maps.places.AutocompletePrediction[] | null> {
    new Promise<google.maps.places.AutocompletePrediction[] | null>((resolve) => {
        this.autocompleteService?.getPlacePredictions({ input: search, types: ["(regions)"] }, (predictions) => {
            if (!predictions) {
              resolve(null);
            } else {
                resolve(predictions.filter((prediction) => prediction.types.includes("country")) || null);
            }
        });
    });
}
Enter fullscreen mode Exit fullscreen mode

The searchPlace method utilizes the Geocoding service to retrieve additional information for a provided place ID obtained from the AutocompleteService response.

searchPlace(search: string): Promise<google.maps.GeocoderResult | null> {
  return new Promise((resolve) => {
    this.geocoder.geocode({ placeId: search }, (results, status) => {
      if (status === "OK" && results && results[0]) {
        resolve(results[0]);
      } else {
        resolve(null);
      }
    });
  });
}
Enter fullscreen mode Exit fullscreen mode

Finally, we will use the getCountry method to parse the geocoder result and obtain the country code.

getCountryCode(place: google.maps.places.PlaceResult): string | false {
  const addressComponents = place.address_components || [];
  for (const component of addressComponents) {
    if (component.types.includes("country")) {
      return component.short_name || false;
    }
    if (component.types.length === 2 && component.types.includes("political")) {
      return component.short_name || false;
    }
  }
  return false;
}
Enter fullscreen mode Exit fullscreen mode

Writing the Autocomplete component

Now we are ready to implement the country autocomplete component using React Select library and the Google Helper class we just created.

import GoogleHelper from "./GoogleHelper";
import AsyncSelect from "react-select/async";
import CountryAutocompleteProps from "./types";

const Google = new GoogleHelper('myKey');

export function CountryAutocomplete(props: CountryAutocompleteProps) {
  const handleCountrySelection = async (country: Option | null) => {
        if (!country) return;
    const place = await Google.searchPlace(country.value as string);
    if (!place) return;
    const countryCode = Google.getCountry(place);
    props.onSelect({ value: countryCode, label: country.label });
    };
    const handleSearchCountries = (inputValue: string) => {
        return new Promise<OptionShape[]>((resolve) => {
            Google
                .searchCountry(inputValue)
                .then((results) => {
                    return resolve(formatAutocompleteResult(results));
                })
                .catch((err) => {
                    return resolve([]);
                });
        });
  }
  return (
    <AsyncSelect
      value={props.value}
      noOptionsMessage={(i) => (!i.inputValue ? "Type to search for a country" : "No results found")}
      placeholder="Type to search for a country"
      loadOptions={handleSearchCountries}
      onChange={handleCountrySelection}
      cacheOptions={true}
      defaultOptions={true}
    />
  )
}
Enter fullscreen mode Exit fullscreen mode

We can see that we are using the AsyncSelect component from React Select. This component allows us to load the options asynchronously, so we can use the loadOptions prop to call our searchCountry function and get all the countries.

We are also defining the handleCountrySelection function that will be called when the user selects a country from the dropdown. This function will call the searchPlace function to get the extra information for the selected country, and then call the onSelect prop to notify the parent component that a country was selected.

Wrapping up

If you want to see the full code, you can visit this GitHub repository, where you will find this same example packed as an npm library to be easily consumed in your projects.

I hope this tutorial has been helpful and helped you to understand a bit better how to use the Google Places API.

If you have any questions or comments, feel free to reach me at @amaggi_ or leave a question on this post.

Top comments (0)