Place Autocomplete Data API

  • The Place Autocomplete Data API allows you to fetch place predictions for autocomplete experiences, even without a map (but if a map is used, it must be a Google Map).

  • You can constrain predictions by location, area, and place type using parameters like locationRestriction , origin , and includedPrimaryTypes .

  • Obtaining detailed information about a place requires calling toPlace() on a prediction, followed by fetchFields() on the resulting Place object to get details like name and address.

  • Session tokens are essential for managing billing; they group related queries and selections into a single billable request, and should be generated uniquely for each user session.

  • Billing is based on queries and selections within a session, with selections incurring a charge for Place data while queries are generally free unless no selection is made within a few minutes.

European Economic Area (EEA) developers

The Place Autocomplete Data API lets you fetch place predictions programmatically, to create customized autocomplete experiences with a finer degree of control than is possible with the autocomplete widget. In this guide you will learn how to use the Place Autocomplete Data API to make autocomplete requests based on user queries.

The following example shows a simplified type-ahead integration. Enter your search query, such as "pizza" or "poke", then click to select the result you want.

Autocomplete requests

An autocomplete request takes a query input string and returns a list of place predictions. To make an autocomplete request, call fetchAutocompleteSuggestions() and pass a request with the needed properties. The input property contains the string to search; in a typical application this value would be updated as the user types a query. The request should include a sessionToken , which is used for billing purposes.

The following snippet shows creating a request body and adding a session token, then calling fetchAutocompleteSuggestions() to get a list of PlacePrediction s.

 // Add an initial request body. 
 let 
  
 request 
  
 = 
  
 { 
  
 input 
 : 
  
 "Tadi" 
 , 
  
 locationRestriction 
 : 
  
 { 
  
 west 
 : 
  
 - 
 122.44 
 , 
  
 north 
 : 
  
 37.8 
 , 
  
 east 
 : 
  
 - 
 122.39 
 , 
  
 south 
 : 
  
 37.78 
 , 
  
 }, 
  
 origin 
 : 
  
 { 
  
 lat 
 : 
  
 37.7893 
 , 
  
 lng 
 : 
  
 - 
 122.4039 
  
 }, 
  
 includedPrimaryTypes 
 : 
  
 [ 
 "restaurant" 
 ], 
  
 language 
 : 
  
 "en-US" 
 , 
  
 region 
 : 
  
 "us" 
 , 
 }; 
 // Create a session token. 
 const 
  
 token 
  
 = 
  
 new 
  
 AutocompleteSessionToken 
 (); 
 // Add the token to the request. 
 // @ts-ignore 
 request 
 . 
 sessionToken 
  
 = 
  
 token 
 ; 
  

Constrain Autocomplete predictions

By default, Place Autocomplete presents all place types, biased for predictions near the user's location, and fetches all available data fields for the user's selected place. Set Place Autocomplete options to present more relevant predictions, by restricting or biasing results.

Restricting results causes the Autocomplete widget to ignore any results that are outside of the restriction area. A common practice is to restrict results to the map bounds. Biasing results makes the Autocomplete widget show results within the specified area, but some matches may be outside of that area.

Use the origin property to specify the origin point from which to calculate geodesic distance to the destination. If this value is omitted, distance is not returned.

Use the includedPrimaryTypes property to specify up to five place types . If no types are specified, places of all types will be returned.

See the API reference

Get place details

To return a Place object from a place prediction result, first call toPlace() , then call fetchFields() on the resulting Place object (the session ID from the place prediction is automatically included). Calling fetchFields() ends the autocomplete session.

 let 
  
 place 
  
 = 
  
 suggestions 
 [ 
 0 
 ]. 
 placePrediction 
 . 
 toPlace 
 (); 
  
 // Get first predicted place. 
 await 
  
 place 
 . 
 fetchFields 
 ({ 
  
 fields 
 : 
  
 [ 
 "displayName" 
 , 
  
 "formattedAddress" 
 ], 
 }); 
 const 
  
 placeInfo 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 "prediction" 
 ); 
 placeInfo 
 . 
 textContent 
  
 = 
  
 "First predicted place: " 
  
 + 
  
 place 
 . 
 displayName 
  
 + 
  
 ": " 
  
 + 
  
 place 
 . 
 formattedAddress 
 ; 
  

Session tokens

Session tokens group the query and selection phases of a user autocomplete search into a discrete session for billing purposes. The session begins when the user starts typing. The session is concluded when the user selects a place and a call to Place Details is made.

To create a new session token and add it to a request, create an instance of AutocompleteSessionToken , then set the sessionToken property of the request to use the tokens as shown in the following snippet:

 // Create a session token. 
 const 
  
 token 
  
 = 
  
 new 
  
 AutocompleteSessionToken 
 (); 
 // Add the token to the request. 
 // @ts-ignore 
 request 
 . 
 sessionToken 
  
 = 
  
 token 
 ; 
  

A session is concluded when fetchFields() is called. After creating the Place instance, you don't need to pass the session token to fetchFields() as this is handled automatically.

 await 
  
 place 
 . 
 fetchFields 
 ({ 
  
 fields 
 : 
  
 [ 
 "displayName" 
 , 
  
 "formattedAddress" 
 ], 
 }); 
  

Make a session token for the next session by creating a new instance of AutocompleteSessionToken .

Session token recommendations:

  • Use session tokens for all Place Autocomplete calls.
  • Generate a fresh token for each session.
  • Pass a unique session token for each new session. Using the same token for more than one session will result in each request being billed individually.

You can optionally omit the autocomplete session token from a request. If the session token is omitted, each request is billed separately, triggering the Autocomplete - Per Request SKU. If you reuse a session token, the session is considered invalid and the requests are charged as if no session token was provided.

Example

As the user types a query, an autocomplete request is called every few keystrokes (not per-character), and a list of possible results is returned. When the user makes a selection from the result list, the selection counts as a request, and all of the requests made during the search are bundled and counted as a single request. If the user selects a place, the search query is available at no charge, and only the Place data request is charged. If the user does not make a selection within a few minutes of the beginning of the session, only the search query is charged.

From the perspective of an app, the flow of events goes like this:

  1. A user begins typing a query to search for "Paris, France".
  2. Upon detecting user input, the app creates a new session token, "Token A".
  3. As the user types, the API makes an autocomplete request every few characters, displaying a new list of potential results for each:
    "P"
    "Par"
    "Paris,"
    "Paris, Fr"
  4. When the user makes a selection:
    • All requests resulting from the query are grouped and added to the session represented by "Token A", as a single request.
    • The user's selection is counted as a Place Detail request, and added to the session represented by "Token A".
  5. The session is concluded, and the app discards "Token A".
Learn about how sessions are billed

Complete example code

This section contains complete examples showing how to use the Place Autocomplete Data API .

Place autocomplete predictions

The following example demonstrates calling fetchAutocompleteSuggestions() for the input "Tadi", then calling toPlace() on the first prediction result, followed by a call to fetchFields() to get place details.

TypeScript

 /** 
 * Demonstrates making a single request for Place predictions, then requests Place Details for the first result. 
 */ 
 async 
  
 function 
  
 init 
 () 
  
 { 
  
 // @ts-ignore 
  
 const 
  
 { 
  
 Place 
 , 
  
 AutocompleteSessionToken 
 , 
  
 AutocompleteSuggestion 
  
 } 
  
 = 
  
 await 
  
 google 
 . 
 maps 
 . 
 importLibrary 
 ( 
 "places" 
 ) 
  
 as 
  
 google 
 . 
 maps 
 . 
 PlacesLibrary 
 ; 
  
 // Add an initial request body. 
  
 let 
  
 request 
  
 = 
  
 { 
  
 input 
 : 
  
 "Tadi" 
 , 
  
 locationRestriction 
 : 
  
 { 
  
 west 
 : 
  
 - 
 122.44 
 , 
  
 north 
 : 
  
 37.8 
 , 
  
 east 
 : 
  
 - 
 122.39 
 , 
  
 south 
 : 
  
 37.78 
  
 }, 
  
 origin 
 : 
  
 { 
  
 lat 
 : 
  
 37.7893 
 , 
  
 lng 
 : 
  
 - 
 122.4039 
  
 }, 
  
 includedPrimaryTypes 
 : 
  
 [ 
 "restaurant" 
 ], 
  
 language 
 : 
  
 "en-US" 
 , 
  
 region 
 : 
  
 "us" 
 , 
  
 }; 
  
 // Create a session token. 
  
 const 
  
 token 
  
 = 
  
 new 
  
 AutocompleteSessionToken 
 (); 
  
 // Add the token to the request. 
  
 // @ts-ignore 
  
 request 
 . 
 sessionToken 
  
 = 
  
 token 
 ; 
  
 // Fetch autocomplete suggestions. 
  
 const 
  
 { 
  
 suggestions 
  
 } 
  
 = 
  
 await 
  
 AutocompleteSuggestion 
 . 
 fetchAutocompleteSuggestions 
 ( 
 request 
 ); 
  
 const 
  
 title 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 'title' 
 ) 
  
 as 
  
 HTMLElement 
 ; 
  
 title 
 . 
 appendChild 
 ( 
 document 
 . 
 createTextNode 
 ( 
 'Query predictions for "' 
  
 + 
  
 request 
 . 
 input 
  
 + 
  
 '":' 
 )); 
  
 for 
  
 ( 
 let 
  
 suggestion 
  
 of 
  
 suggestions 
 ) 
  
 { 
  
 const 
  
 placePrediction 
  
 = 
  
 suggestion 
 . 
 placePrediction 
 ; 
  
 // Create a new list element. 
  
 const 
  
 listItem 
  
 = 
  
 document 
 . 
 createElement 
 ( 
 'li' 
 ); 
  
 const 
  
 resultsElement 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 "results" 
 ) 
  
 as 
  
 HTMLElement 
 ; 
  
 listItem 
 . 
 appendChild 
 ( 
 document 
 . 
 createTextNode 
 ( 
 placePrediction 
 . 
 text 
 . 
 toString 
 ())); 
  
 resultsElement 
 . 
 appendChild 
 ( 
 listItem 
 ); 
  
 } 
  
 let 
  
 place 
  
 = 
  
 suggestions 
 [ 
 0 
 ]. 
 placePrediction 
 . 
 toPlace 
 (); 
  
 // Get first predicted place. 
  
 await 
  
 place 
 . 
 fetchFields 
 ({ 
  
 fields 
 : 
  
 [ 
 'displayName' 
 , 
  
 'formattedAddress' 
 ], 
  
 }); 
  
 const 
  
 placeInfo 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 "prediction" 
 ) 
  
 as 
  
 HTMLElement 
 ; 
  
 placeInfo 
 . 
 textContent 
  
 = 
  
 'First predicted place: ' 
  
 + 
  
 place 
 . 
 displayName 
  
 + 
  
 ': ' 
  
 + 
  
 place 
 . 
 formattedAddress 
 ; 
 } 
 init 
 (); 
  

JavaScript

 /** 
 * Demonstrates making a single request for Place predictions, then requests Place Details for the first result. 
 */ 
 async 
  
 function 
  
 init 
 () 
  
 { 
  
 // @ts-ignore 
  
 const 
  
 { 
  
 Place 
 , 
  
 AutocompleteSessionToken 
 , 
  
 AutocompleteSuggestion 
  
 } 
  
 = 
  
 await 
  
 google 
 . 
 maps 
 . 
 importLibrary 
 ( 
 "places" 
 ); 
  
 // Add an initial request body. 
  
 let 
  
 request 
  
 = 
  
 { 
  
 input 
 : 
  
 "Tadi" 
 , 
  
 locationRestriction 
 : 
  
 { 
  
 west 
 : 
  
 - 
 122.44 
 , 
  
 north 
 : 
  
 37.8 
 , 
  
 east 
 : 
  
 - 
 122.39 
 , 
  
 south 
 : 
  
 37.78 
 , 
  
 }, 
  
 origin 
 : 
  
 { 
  
 lat 
 : 
  
 37.7893 
 , 
  
 lng 
 : 
  
 - 
 122.4039 
  
 }, 
  
 includedPrimaryTypes 
 : 
  
 [ 
 "restaurant" 
 ], 
  
 language 
 : 
  
 "en-US" 
 , 
  
 region 
 : 
  
 "us" 
 , 
  
 }; 
  
 // Create a session token. 
  
 const 
  
 token 
  
 = 
  
 new 
  
 AutocompleteSessionToken 
 (); 
  
 // Add the token to the request. 
  
 // @ts-ignore 
  
 request 
 . 
 sessionToken 
  
 = 
  
 token 
 ; 
  
 // Fetch autocomplete suggestions. 
  
 const 
  
 { 
  
 suggestions 
  
 } 
  
 = 
  
 await 
  
 AutocompleteSuggestion 
 . 
 fetchAutocompleteSuggestions 
 ( 
 request 
 ); 
  
 const 
  
 title 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 "title" 
 ); 
  
 title 
 . 
 appendChild 
 ( 
  
 document 
 . 
 createTextNode 
 ( 
 'Query predictions for "' 
  
 + 
  
 request 
 . 
 input 
  
 + 
  
 '":' 
 ), 
  
 ); 
  
 for 
  
 ( 
 let 
  
 suggestion 
  
 of 
  
 suggestions 
 ) 
  
 { 
  
 const 
  
 placePrediction 
  
 = 
  
 suggestion 
 . 
 placePrediction 
 ; 
  
 // Create a new list element. 
  
 const 
  
 listItem 
  
 = 
  
 document 
 . 
 createElement 
 ( 
 "li" 
 ); 
  
 const 
  
 resultsElement 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 "results" 
 ); 
  
 listItem 
 . 
 appendChild 
 ( 
  
 document 
 . 
 createTextNode 
 ( 
 placePrediction 
 . 
 text 
 . 
 toString 
 ()), 
  
 ); 
  
 resultsElement 
 . 
 appendChild 
 ( 
 listItem 
 ); 
  
 } 
  
 let 
  
 place 
  
 = 
  
 suggestions 
 [ 
 0 
 ]. 
 placePrediction 
 . 
 toPlace 
 (); 
  
 // Get first predicted place. 
  
 await 
  
 place 
 . 
 fetchFields 
 ({ 
  
 fields 
 : 
  
 [ 
 "displayName" 
 , 
  
 "formattedAddress" 
 ], 
  
 }); 
  
 const 
  
 placeInfo 
  
 = 
  
 document 
 . 
 getElementById 
 ( 
 "prediction" 
 ); 
  
 placeInfo 
 . 
 textContent 
  
 = 
  
 "First predicted place: " 
  
 + 
  
 place 
 . 
 displayName 
  
 + 
  
 ": " 
  
 + 
  
 place 
 . 
 formattedAddress 
 ; 
 } 
 init 
 (); 
  

CSS

 /* 
 * Always set the map height explicitly to define the size of the div element 
 * that contains the map. 
 */ 
 # 
 map 
  
 { 
  
 height 
 : 
  
 100 
 % 
 ; 
 } 
 /* 
 * Optional: Makes the sample page fill the window. 
 */ 
 html 
 , 
 body 
  
 { 
  
 height 
 : 
  
 100 
 % 
 ; 
  
 margin 
 : 
  
 0 
 ; 
  
 padding 
 : 
  
 0 
 ; 
 } 
  

HTML

<html>
  <head>
    <title>Place Autocomplete Data API Predictions</title>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <div id="title"></div>
    <ul id="results"></ul>
    <p><span id="prediction"></span></p>
    <img
      class="powered-by-google"
      src="https://storage.googleapis.com/geo-devrel-public-buckets/powered_by_google_on_white.png"
      alt="Powered by Google"
    />

    <!-- prettier-ignore -->
    <script>(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})
        ({key: "AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg", v: "weekly"});</script>
  </body>
</html>  

Try Sample

Place autocomplete type-ahead with sessions

This example demonstrates the following concepts:

  • Calling fetchAutocompleteSuggestions() based on user queries and showing a list of predicted places in response.
  • Using session tokens to group a user query with the final Place Details request.
  • Retrieving place details for the selected place and displaying a marker.
  • Using control slotting to nest UI elements in the gmp-map element.

TypeScript

 const 
  
 mapElement 
  
 = 
  
 document 
 . 
 querySelector 
 ( 
 'gmp-map' 
 ) 
  
 as 
  
 google 
 . 
 maps 
 . 
 MapElement 
 ; 
 let 
  
 innerMap 
 : 
  
 google.maps.Map 
 ; 
 let 
  
 marker 
 : 
  
 google.maps.marker.AdvancedMarkerElement 
 ; 
 let 
  
 titleElement 
  
 = 
  
 document 
 . 
 querySelector 
 ( 
 '.title' 
 ) 
  
 as 
  
 HTMLElement 
 ; 
 let 
  
 resultsContainerElement 
  
 = 
  
 document 
 . 
 querySelector 
 ( 
 '.results' 
 ) 
  
 as 
  
 HTMLElement 
 ; 
 let 
  
 inputElement 
  
 = 
  
 document 
 . 
 querySelector 
 ( 
 'input' 
 ) 
  
 as 
  
 HTMLInputElement 
 ; 
 let 
  
 tokenStatusElement 
  
 = 
  
 document 
 . 
 querySelector 
 ( 
 '.token-status' 
 ) 
  
 as 
  
 HTMLElement 
 ; 
 let 
  
 newestRequestId 
  
 = 
  
 0 
 ; 
 let 
  
 tokenCount 
  
 = 
  
 0 
 ; 
 // Create an initial request body. 
 const 
  
 request 
 : 
  
 google.maps.places.AutocompleteRequest 
  
 = 
  
 { 
  
 input 
 : 
  
 '' 
 , 
  
 includedPrimaryTypes 
 : 
  
 [ 
  
 'restaurant' 
 , 
  
 'cafe' 
 , 
  
 'museum' 
 , 
  
 'park' 
 , 
  
 'botanical_garden' 
 , 
  
 ], 
 } 
 async 
  
 function 
  
 init 
 () 
  
 { 
  
 await 
  
 google 
 . 
 maps 
 . 
 importLibrary 
 ( 
 'maps' 
 ); 
  
 innerMap 
  
 = 
  
 mapElement 
 . 
 innerMap 
 ; 
  
 innerMap 
 . 
 setOptions 
 ({ 
  
 mapTypeControl 
 : 
  
 false 
 , 
  
 }); 
  
 // Update request center and bounds when the map bounds change. 
  
 google 
 . 
 maps 
 . 
 event 
 . 
 addListener 
 ( 
 innerMap 
 , 
  
 'bounds_changed' 
 , 
  
 async 
  
 () 
  
 = 
>  
 { 
  
 request 
 . 
 locationRestriction 
  
 = 
  
 innerMap 
 . 
 getBounds 
 (); 
  
 request 
 . 
 origin 
  
 = 
  
 innerMap 
 . 
 getCenter 
 (); 
  
 }); 
  
 inputElement 
 . 
 addEventListener 
 ( 
 'input' 
 , 
  
 makeAutocompleteRequest 
 ); 
 } 
 async 
  
 function 
  
 makeAutocompleteRequest 
 ( 
 inputEvent 
 ) 
  
 { 
  
 // To avoid race conditions, store the request ID and compare after the request. 
  
 const 
  
 requestId 
  
 = 
  
 ++ 
 newestRequestId 
 ; 
  
 const 
  
 { 
  
 AutocompleteSuggestion 
  
 } 
  
 = 
  
 ( 
 await 
  
 google 
 . 
 maps 
 . 
 importLibrary 
 ( 
  
 'places' 
  
 )) 
  
 as 
  
 google 
 . 
 maps 
 . 
 PlacesLibrary 
 ; 
  
 if 
  
 ( 
 ! 
 inputEvent 
 . 
 target 
 ? 
 . 
 value 
 ) 
  
 { 
  
 titleElement 
 . 
 textContent 
  
 = 
  
 '' 
 ; 
  
 resultsContainerElement 
 . 
 replaceChildren 
 (); 
  
 return 
 ; 
  
 } 
  
 // Add the latest char sequence to the request. 
  
 request 
 . 
 input 
  
 = 
  
 ( 
 inputEvent 
 . 
 target 
  
 as 
  
 HTMLInputElement 
 ). 
 value 
 ; 
  
 // Fetch autocomplete suggestions and show them in a list. 
  
 const 
  
 { 
  
 suggestions 
  
 } 
  
 = 
  
 await 
  
 AutocompleteSuggestion 
 . 
 fetchAutocompleteSuggestions 
 ( 
 request 
 ); 
  
 // If the request has been superseded by a newer request, do not render the output. 
  
 if 
  
 ( 
 requestId 
  
 !== 
  
 newestRequestId 
 ) 
  
 return 
 ; 
  
 titleElement 
 . 
 innerText 
  
 = 
  
 `Place predictions for " 
 ${ 
 request 
 . 
 input 
 } 
 "` 
 ; 
  
 // Clear the list first. 
  
 resultsContainerElement 
 . 
 replaceChildren 
 (); 
  
 for 
  
 ( 
 const 
  
 suggestion 
  
 of 
  
 suggestions 
 ) 
  
 { 
  
 const 
  
 placePrediction 
  
 = 
  
 suggestion 
 . 
 placePrediction 
 ; 
  
 if 
  
 ( 
 ! 
 placePrediction 
 ) 
  
 { 
  
 continue 
 ; 
  
 } 
  
 // Create a link for the place, add an event handler to fetch the place. 
  
 // We are using a button element to take advantage of its a11y capabilities. 
  
 const 
  
 placeButton 
  
 = 
  
 document 
 . 
 createElement 
 ( 
 'button' 
 ); 
  
 placeButton 
 . 
 addEventListener 
 ( 
 'click' 
 , 
  
 () 
  
 = 
>  
 { 
  
 onPlaceSelected 
 ( 
 placePrediction 
 . 
 toPlace 
 ()); 
  
 }); 
  
 placeButton 
 . 
 textContent 
  
 = 
  
 placePrediction 
 . 
 text 
 . 
 toString 
 (); 
  
 placeButton 
 . 
 classList 
 . 
 add 
 ( 
 'place-button' 
 ); 
  
 // Create a new list item element. 
  
 const 
  
 li 
  
 = 
  
 document 
 . 
 createElement 
 ( 
 'li' 
 ); 
  
 li 
 . 
 appendChild 
 ( 
 placeButton 
 ); 
  
 resultsContainerElement 
 . 
 appendChild 
 ( 
 li 
 ); 
  
 } 
 } 
 // Event handler for clicking on a suggested place. 
 async 
  
 function 
  
 onPlaceSelected 
 ( 
 place 
 : 
  
 google.maps.places.Place 
 ) 
  
 { 
  
 const 
  
 { 
  
 AdvancedMarkerElement 
  
 } 
  
 = 
  
 ( 
 await 
  
 google 
 . 
 maps 
 . 
 importLibrary 
 ( 
  
 'marker' 
  
 )) 
  
 as 
  
 google 
 . 
 maps 
 . 
 MarkerLibrary 
 ; 
  
 await 
  
 place 
 . 
 fetchFields 
 ({ 
  
 fields 
 : 
  
 [ 
 'displayName' 
 , 
  
 'formattedAddress' 
 , 
  
 'location' 
 ], 
  
 }); 
  
 resultsContainerElement 
 . 
 textContent 
  
 = 
  
 ` 
 ${ 
 place 
 . 
 displayName 
 } 
 : 
 ${ 
 place 
 . 
 formattedAddress 
 } 
 ` 
 ; 
  
 titleElement 
 . 
 textContent 
  
 = 
  
 'Selected Place:' 
 ; 
  
 inputElement 
 . 
 value 
  
 = 
  
 '' 
 ; 
  
 await 
  
 refreshToken 
 (); 
  
 // Remove the previous marker, if it exists. 
  
 if 
  
 ( 
 marker 
 ) 
  
 { 
  
 marker 
 . 
 remove 
 (); 
  
 } 
  
 // Create a new marker. 
  
 marker 
  
 = 
  
 new 
  
 AdvancedMarkerElement 
 ({ 
  
 map 
 : 
  
 innerMap 
 , 
  
 position 
 : 
  
 place.location 
 , 
  
 title 
 : 
  
 place.displayName 
 , 
  
 }) 
  
 // Center the map on the selected place. 
  
 if 
  
 ( 
 place 
 . 
 location 
 ) 
  
 { 
  
 innerMap 
 . 
 setCenter 
 ( 
 place 
 . 
 location 
 ); 
  
 innerMap 
 . 
 setZoom 
 ( 
 15 
 ); 
  
 } 
 } 
 // Helper function to refresh the session token. 
 async 
  
 function 
  
 refreshToken 
 () 
  
 { 
  
 const 
  
 { 
  
 AutocompleteSessionToken 
  
 } 
  
 = 
  
 ( 
 await 
  
 google 
 . 
 maps 
 . 
 importLibrary 
 ( 
  
 'places' 
  
 )) 
  
 as 
  
 google 
 . 
 maps 
 . 
 PlacesLibrary 
 ; 
  
 // Increment the token counter. 
  
 tokenCount 
 ++ 
 ; 
  
 // Create a new session token and add it to the request. 
  
 request 
 . 
 sessionToken 
  
 = 
  
 new 
  
 AutocompleteSessionToken 
 (); 
  
 tokenStatusElement 
 . 
 textContent 
  
 = 
  
 `Session token count: 
 ${ 
 tokenCount 
 } 
 ` 
 ; 
 } 
 init 
 (); 
  

JavaScript

 const 
  
 mapElement 
  
 = 
  
 document 
 . 
 querySelector 
 ( 
 'gmp-map' 
 ); 
 let 
  
 innerMap 
 ; 
 let 
  
 marker 
 ; 
 let 
  
 titleElement 
  
 = 
  
 document 
 . 
 querySelector 
 ( 
 '.title' 
 ); 
 let 
  
 resultsContainerElement 
  
 = 
  
 document 
 . 
 querySelector 
 ( 
 '.results' 
 ); 
 let 
  
 inputElement 
  
 = 
  
 document 
 . 
 querySelector 
 ( 
 'input' 
 ); 
 let 
  
 tokenStatusElement 
  
 = 
  
 document 
 . 
 querySelector 
 ( 
 '.token-status' 
 ); 
 let 
  
 newestRequestId 
  
 = 
  
 0 
 ; 
 let 
  
 tokenCount 
  
 = 
  
 0 
 ; 
 // Create an initial request body. 
 const 
  
 request 
  
 = 
  
 { 
  
 input 
 : 
  
 '' 
 , 
  
 includedPrimaryTypes 
 : 
  
 [ 
  
 'restaurant' 
 , 
  
 'cafe' 
 , 
  
 'museum' 
 , 
  
 'park' 
 , 
  
 'botanical_garden' 
 , 
  
 ], 
 }; 
 async 
  
 function 
  
 init 
 () 
  
 { 
  
 await 
  
 google 
 . 
 maps 
 . 
 importLibrary 
 ( 
 'maps' 
 ); 
  
 innerMap 
  
 = 
  
 mapElement 
 . 
 innerMap 
 ; 
  
 innerMap 
 . 
 setOptions 
 ({ 
  
 mapTypeControl 
 : 
  
 false 
 , 
  
 }); 
  
 // Update request center and bounds when the map bounds change. 
  
 google 
 . 
 maps 
 . 
 event 
 . 
 addListener 
 ( 
 innerMap 
 , 
  
 'bounds_changed' 
 , 
  
 async 
  
 () 
  
 = 
>  
 { 
  
 request 
 . 
 locationRestriction 
  
 = 
  
 innerMap 
 . 
 getBounds 
 (); 
  
 request 
 . 
 origin 
  
 = 
  
 innerMap 
 . 
 getCenter 
 (); 
  
 }); 
  
 inputElement 
 . 
 addEventListener 
 ( 
 'input' 
 , 
  
 makeAutocompleteRequest 
 ); 
 } 
 async 
  
 function 
  
 makeAutocompleteRequest 
 ( 
 inputEvent 
 ) 
  
 { 
  
 // To avoid race conditions, store the request ID and compare after the request. 
  
 const 
  
 requestId 
  
 = 
  
 ++ 
 newestRequestId 
 ; 
  
 const 
  
 { 
  
 AutocompleteSuggestion 
  
 } 
  
 = 
  
 ( 
 await 
  
 google 
 . 
 maps 
 . 
 importLibrary 
 ( 
 'places' 
 )); 
  
 if 
  
 ( 
 ! 
 inputEvent 
 . 
 target 
 ? 
 . 
 value 
 ) 
  
 { 
  
 titleElement 
 . 
 textContent 
  
 = 
  
 '' 
 ; 
  
 resultsContainerElement 
 . 
 replaceChildren 
 (); 
  
 return 
 ; 
  
 } 
  
 // Add the latest char sequence to the request. 
  
 request 
 . 
 input 
  
 = 
  
 inputEvent 
 . 
 target 
 . 
 value 
 ; 
  
 // Fetch autocomplete suggestions and show them in a list. 
  
 const 
  
 { 
  
 suggestions 
  
 } 
  
 = 
  
 await 
  
 AutocompleteSuggestion 
 . 
 fetchAutocompleteSuggestions 
 ( 
 request 
 ); 
  
 // If the request has been superseded by a newer request, do not render the output. 
  
 if 
  
 ( 
 requestId 
  
 !== 
  
 newestRequestId 
 ) 
  
 return 
 ; 
  
 titleElement 
 . 
 innerText 
  
 = 
  
 `Place predictions for " 
 ${ 
 request 
 . 
 input 
 } 
 "` 
 ; 
  
 // Clear the list first. 
  
 resultsContainerElement 
 . 
 replaceChildren 
 (); 
  
 for 
  
 ( 
 const 
  
 suggestion 
  
 of 
  
 suggestions 
 ) 
  
 { 
  
 const 
  
 placePrediction 
  
 = 
  
 suggestion 
 . 
 placePrediction 
 ; 
  
 if 
  
 ( 
 ! 
 placePrediction 
 ) 
  
 { 
  
 continue 
 ; 
  
 } 
  
 // Create a link for the place, add an event handler to fetch the place. 
  
 // We are using a button element to take advantage of its a11y capabilities. 
  
 const 
  
 placeButton 
  
 = 
  
 document 
 . 
 createElement 
 ( 
 'button' 
 ); 
  
 placeButton 
 . 
 addEventListener 
 ( 
 'click' 
 , 
  
 () 
  
 = 
>  
 { 
  
 onPlaceSelected 
 ( 
 placePrediction 
 . 
 toPlace 
 ()); 
  
 }); 
  
 placeButton 
 . 
 textContent 
  
 = 
  
 placePrediction 
 . 
 text 
 . 
 toString 
 (); 
  
 placeButton 
 . 
 classList 
 . 
 add 
 ( 
 'place-button' 
 ); 
  
 // Create a new list item element. 
  
 const 
  
 li 
  
 = 
  
 document 
 . 
 createElement 
 ( 
 'li' 
 ); 
  
 li 
 . 
 appendChild 
 ( 
 placeButton 
 ); 
  
 resultsContainerElement 
 . 
 appendChild 
 ( 
 li 
 ); 
  
 } 
 } 
 // Event handler for clicking on a suggested place. 
 async 
  
 function 
  
 onPlaceSelected 
 ( 
 place 
 ) 
  
 { 
  
 const 
  
 { 
  
 AdvancedMarkerElement 
  
 } 
  
 = 
  
 ( 
 await 
  
 google 
 . 
 maps 
 . 
 importLibrary 
 ( 
 'marker' 
 )); 
  
 await 
  
 place 
 . 
 fetchFields 
 ({ 
  
 fields 
 : 
  
 [ 
 'displayName' 
 , 
  
 'formattedAddress' 
 , 
  
 'location' 
 ], 
  
 }); 
  
 resultsContainerElement 
 . 
 textContent 
  
 = 
  
 ` 
 ${ 
 place 
 . 
 displayName 
 } 
 : 
 ${ 
 place 
 . 
 formattedAddress 
 } 
 ` 
 ; 
  
 titleElement 
 . 
 textContent 
  
 = 
  
 'Selected Place:' 
 ; 
  
 inputElement 
 . 
 value 
  
 = 
  
 '' 
 ; 
  
 await 
  
 refreshToken 
 (); 
  
 // Remove the previous marker, if it exists. 
  
 if 
  
 ( 
 marker 
 ) 
  
 { 
  
 marker 
 . 
 remove 
 (); 
  
 } 
  
 // Create a new marker. 
  
 marker 
  
 = 
  
 new 
  
 AdvancedMarkerElement 
 ({ 
  
 map 
 : 
  
 innerMap 
 , 
  
 position 
 : 
  
 place 
 . 
 location 
 , 
  
 title 
 : 
  
 place 
 . 
 displayName 
 , 
  
 }); 
  
 // Center the map on the selected place. 
  
 if 
  
 ( 
 place 
 . 
 location 
 ) 
  
 { 
  
 innerMap 
 . 
 setCenter 
 ( 
 place 
 . 
 location 
 ); 
  
 innerMap 
 . 
 setZoom 
 ( 
 15 
 ); 
  
 } 
 } 
 // Helper function to refresh the session token. 
 async 
  
 function 
  
 refreshToken 
 () 
  
 { 
  
 const 
  
 { 
  
 AutocompleteSessionToken 
  
 } 
  
 = 
  
 ( 
 await 
  
 google 
 . 
 maps 
 . 
 importLibrary 
 ( 
 'places' 
 )); 
  
 // Increment the token counter. 
  
 tokenCount 
 ++ 
 ; 
  
 // Create a new session token and add it to the request. 
  
 request 
 . 
 sessionToken 
  
 = 
  
 new 
  
 AutocompleteSessionToken 
 (); 
  
 tokenStatusElement 
 . 
 textContent 
  
 = 
  
 `Session token count: 
 ${ 
 tokenCount 
 } 
 ` 
 ; 
 } 
 init 
 (); 
  

CSS

 /* 
 * Always set the map height explicitly to define the size of the div element 
 * that contains the map. 
 */ 
 gmp-map 
  
 { 
  
 height 
 : 
  
 100 
 % 
 ; 
 } 
 /* 
 * Optional: Makes the sample page fill the window. 
 */ 
 html 
 , 
 body 
  
 { 
  
 height 
 : 
  
 100 
 % 
 ; 
  
 margin 
 : 
  
 0 
 ; 
  
 padding 
 : 
  
 0 
 ; 
 } 
 . 
 place-button 
  
 { 
  
 height 
 : 
  
 3 
 rem 
 ; 
  
 width 
 : 
  
 100 
 % 
 ; 
  
 background-color 
 : 
  
 transparent 
 ; 
  
 text-align 
 : 
  
 left 
 ; 
  
 border 
 : 
  
 none 
 ; 
  
 cursor 
 : 
  
 pointer 
 ; 
 } 
 . 
 place-button 
 : 
 focus-visible 
  
 { 
  
 outline 
 : 
  
 2 
 px 
  
 solid 
  
 #0056b3 
 ; 
  
 border-radius 
 : 
  
 2 
 px 
 ; 
 } 
 . 
 input 
  
 { 
  
 width 
 : 
  
 300 
 px 
 ; 
  
 font-size 
 : 
  
 small 
 ; 
  
 margin-bottom 
 : 
  
 1 
 rem 
 ; 
 } 
 /* Styles for the floating panel */ 
 . 
 controls 
  
 { 
  
 background-color 
 : 
  
 #fff 
 ; 
  
 border-radius 
 : 
  
 8 
 px 
 ; 
  
 box-shadow 
 : 
  
 0 
  
 2 
 px 
  
 6 
 px 
  
 rgba 
 ( 
 0 
 , 
  
 0 
 , 
  
 0 
 , 
  
 0.3 
 ); 
  
 font-family 
 : 
  
 sans-serif 
 ; 
  
 font-size 
 : 
  
 small 
 ; 
  
 margin 
 : 
  
 12 
 px 
 ; 
  
 padding 
 : 
  
 1 
 rem 
 ; 
 } 
 . 
 title 
  
 { 
  
 font-weight 
 : 
  
 bold 
 ; 
  
 margin-top 
 : 
  
 1 
 rem 
 ; 
  
 margin-bottom 
 : 
  
 0.5 
 rem 
 ; 
 } 
 . 
 results 
  
 { 
  
 list-style-type 
 : 
  
 none 
 ; 
  
 margin 
 : 
  
 0 
 ; 
  
 padding 
 : 
  
 0 
 ; 
 } 
 . 
 results 
  
 li 
 : 
 not 
 ( 
 : 
 last-child 
 ) 
  
 { 
  
 border-bottom 
 : 
  
 1 
 px 
  
 solid 
  
 #ddd 
 ; 
 } 
 . 
 results 
  
 li 
 : 
 hover 
  
 { 
  
 background-color 
 : 
  
 #eee 
 ; 
 } 
  

HTML

<html>
    <head>
        <title>Place Autocomplete Data API Session</title>

        <link rel="stylesheet" type="text/css" href="./style.css" />
        <script type="module" src="./index.js"></script>
        <!-- prettier-ignore -->
        <script>(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})
        ({key: "AIzaSyA6myHzS10YXdcazAFalmXvDkrYCp5cLc8", v: "weekly"});</script>
    </head>
    <body>
        <gmp-map center="37.7893, -122.4039" zoom="12" map-id="DEMO_MAP_ID">
            <div
                class="controls"
                slot="control-inline-start-block-start"
            >
                <input
                    type="text"
                    class="input"
                    placeholder="Search for a place..."
                    autocomplete="off"
                /><!-- Turn off the input's own autocomplete (not supported by all browsers).-->
                <div class="token-status"></div>
                <div class="title"></div>
                <ol class="results"></ol>
            </div>
        </gmp-map>
    </body>
</html>  

Try Sample

Create a Mobile Website
View Site in Mobile | Classic
Share by: