Migrate to the new Place Search

This page explains the differences between text-based place search features in the Place class (new) and the PlacesService (legacy), and provides some code snippets for comparison.

The legacy PlacesService has the following text-based search methods:

  • The findPlaceFromQuery() method which takes a text query and returns a single place result, and supports the use of place data fields.
  • The findPlaceFromPhoneNumber() method which lets you search for a place using a phone number, and supports the use of place data fields.
  • The textSearch() method which takes a text query and returns a list of place results. textSearch() is older, and does not support the use of place data fields.

The new Place class offers the Place.searchByText() method, which lets you search for places using either a text query or phone number, and lets you customize your searches using an expanded selection of regularly updated place data fields and place types.

The following table lists some of the main differences in place search methods between the Place class and PlacesService:

PlacesService (Legacy) Place (New)
findPlaceFromQuery()
findPlaceFromPhoneNumber()
searchByText()
FindPlaceFromQueryRequest
FindPlaceFromPhoneNumberRequest
SearchByTextRequest
Limited query options. More expansive query options.
Requires the use of a callback to handle the results object and google.maps.places.PlacesServiceStatus response. Uses Promises, and works asynchronously.
Requires a PlacesServiceStatus check. No required status check, can use standard error handling.
Supports only location bias. Supports location bias and location restriction.
Place data fields are formatted using snake case. Place data fields are formatted using camel case.
Returns a single place result. Returns up to 20 place results.
Limited to a fixed set of place types and place data fields. Provides an expanded selection of regularly updated place types and place data fields.
textSearch()
searchByText()
Returns all available data fields (a subset of the supported fields); cannot be constrained to specific fields. Returns only the requested place data fields.

Code comparison

This section compares code for text search methods to illustrate the differences between the Places service and the Place class. The code snippets show the code required on each respective API to make a text-based search request.

Places service (Legacy)

The following code snippet shows using the findPlaceFromQuery() method to search for a place. The request is synchronous, and includes a conditional check on PlacesServiceStatus. The needed place data fields are specified in the request body, which is defined prior to making the actual request.

function findPlaces() {
  const request = {
    query: "Museum of Contemporary Art Australia",
    fields: ["name", "geometry"],
  };

  // Create an instance of PlacesService.
  service = new google.maps.places.PlacesService(map);

  // Make a findPlaceFromQuery request.
  service.findPlaceFromQuery(request, (results, status) => {
    let place = results[0];
    if (status === google.maps.places.PlacesServiceStatus.OK && results) {
      if (!place.geometry || !place.geometry.location) return;

      const marker = new google.maps.Marker({
        map,
        position: place.geometry.location,
      });
      map.setCenter(place.geometry.location);
    }
  });
}

Learn more

Text Search (New)

The following code snippet shows using the searchByText() method to search for places. The request is asynchronous, and does not require a status check (standard error handling can be used). In this example, the request includes a maxResultCount of 8 (value must be between 1 and 20). This function loops through the results and adds a marker for each one, adjusting the map bounds based on the position of the markers. Because the searchByText() method uses the await operator it can only be used inside an async function.

async function findPlaces() {
  // Define a request.
  // The `fields` property is required; all others are optional.
  const request = {
    fields: ["displayName", "location", "businessStatus"],
    textQuery: "Tacos in Mountain View",
    includedType: "restaurant",
    locationBias: { lat: 37.4161493, lng: -122.0812166 },
    isOpenNow: true,
    language: "en-US",
    maxResultCount: 8,
    minRating: 3.2,
    region: "us",
    useStrictTypeFiltering: false,
  };

  // Call searchByText passing the request.
  const { places } = await google.maps.places.Place.searchByText(request);

  // Add a marker for each result.
  if (places.length) {
    const bounds = new google.maps.LatLngBounds();

    places.forEach((place) => {
      const markerView = new google.maps.marker.AdvancedMarkerElement({
        map,
        position: place.location,
        title: place.displayName,
      });

      bounds.extend(place.location);
      console.log(place);
    });
    map.fitBounds(bounds);
  } else {
    console.log("No results");
  }
}

The searchByText() method supports many more request options compared to the previous version, including:

  • includedType which lets you constrain searches to a specific place type.
  • isOpenNow which lets you restrict searches to only return places that are open.
  • minRating which lets you filter out results below the specified limit (for example, only return places with three stars or more).
  • locationRestriction which omits results outside of the specified location (locationBias is also supported).

Learn more