Place Autocomplete  |  Maps JavaScript API  |  Google for Developers

TypeScript

const mapElement = document.querySelector('gmp-map') as google.maps.MapElement;
const placeAutocomplete = document.querySelector(
    'gmp-place-autocomplete'
) as google.maps.places.PlaceAutocompleteElement;
let innerMap;
let marker: google.maps.marker.AdvancedMarkerElement;
let infoWindow: google.maps.InfoWindow;
let center = { lat: 40.749933, lng: -73.98633 }; // New York City
async function initMap(): Promise<void> {
    // Request needed libraries.
    const [] = await Promise.all([
        google.maps.importLibrary('marker'),
        google.maps.importLibrary('places'),
    ]);

    // Get the inner map.
    innerMap = mapElement.innerMap;
    innerMap.setOptions({
        mapTypeControl: false,
    });

    // Use the bounds_changed event to restrict results to the current map bounds.
    google.maps.event.addListener(innerMap, 'bounds_changed', async () => {
        placeAutocomplete.locationRestriction = innerMap.getBounds();
    });

    // Create the marker and infowindow.
    marker = new google.maps.marker.AdvancedMarkerElement({
        map: innerMap,
    });

    infoWindow = new google.maps.InfoWindow({});

    // Add the gmp-placeselect listener, and display the results on the map.
    //prettier-ignore
    //@ts-ignore
    placeAutocomplete.addEventListener('gmp-select', async ({ placePrediction }) => {
      const place = placePrediction.toPlace();
      await place.fetchFields({
        fields: ['displayName', 'formattedAddress', 'location'],
      });

      // If the place has a geometry, then present it on a map.
      if (place.viewport) {
        innerMap.fitBounds(place.viewport);
      } else {
        innerMap.setCenter(place.location);
        innerMap.setZoom(17);
      }

      let content = document.createElement('div');
      let nameText = document.createElement('span');
      nameText.textContent = place.displayName;
      content.appendChild(nameText);
      content.appendChild(document.createElement('br'));
      let addressText = document.createElement('span');
      addressText.textContent = place.formattedAddress;
      content.appendChild(addressText);

      updateInfoWindow(content, place.location);
      marker.position = place.location;
    }
  );
}

// Helper function to create an info window.
function updateInfoWindow(content, center) {
    infoWindow.setContent(content);
    infoWindow.setPosition(center);
    infoWindow.open({
        map: innerMap,
        anchor: marker,
        shouldFocus: false,
    });
}

initMap();

JavaScript

const mapElement = document.querySelector('gmp-map');
const placeAutocomplete = document.querySelector('gmp-place-autocomplete');
let innerMap;
let marker;
let infoWindow;
let center = { lat: 40.749933, lng: -73.98633 }; // New York City
async function initMap() {
    // Request needed libraries.
    const [] = await Promise.all([
        google.maps.importLibrary('marker'),
        google.maps.importLibrary('places'),
    ]);
    // Get the inner map.
    innerMap = mapElement.innerMap;
    innerMap.setOptions({
        mapTypeControl: false,
    });
    // Use the bounds_changed event to restrict results to the current map bounds.
    google.maps.event.addListener(innerMap, 'bounds_changed', async () => {
        placeAutocomplete.locationRestriction = innerMap.getBounds();
    });
    // Create the marker and infowindow.
    marker = new google.maps.marker.AdvancedMarkerElement({
        map: innerMap,
    });
    infoWindow = new google.maps.InfoWindow({});
    // Add the gmp-placeselect listener, and display the results on the map.
    //prettier-ignore
    //@ts-ignore
    placeAutocomplete.addEventListener('gmp-select', async ({ placePrediction }) => {
        const place = placePrediction.toPlace();
        await place.fetchFields({
            fields: ['displayName', 'formattedAddress', 'location'],
        });
        // If the place has a geometry, then present it on a map.
        if (place.viewport) {
            innerMap.fitBounds(place.viewport);
        }
        else {
            innerMap.setCenter(place.location);
            innerMap.setZoom(17);
        }
        let content = document.createElement('div');
        let nameText = document.createElement('span');
        nameText.textContent = place.displayName;
        content.appendChild(nameText);
        content.appendChild(document.createElement('br'));
        let addressText = document.createElement('span');
        addressText.textContent = place.formattedAddress;
        content.appendChild(addressText);
        updateInfoWindow(content, place.location);
        marker.position = place.location;
    });
}
// Helper function to create an info window.
function updateInfoWindow(content, center) {
    infoWindow.setContent(content);
    infoWindow.setPosition(center);
    infoWindow.open({
        map: innerMap,
        anchor: marker,
        shouldFocus: false,
    });
}
initMap();

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-autocomplete-card {
    background-color: #fff;
    border-radius: 5px;
    box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
    margin: 10px;
    padding: 5px;
    font-family: Roboto, sans-serif;
    font-size: small;
}

gmp-place-autocomplete {
    width: 300px;
}

#infowindow-content .title {
    font-weight: bold;
}

#map #infowindow-content {
    display: inline;
}

HTML

<html>
    <head>
        <title>Place Autocomplete map</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="40.749933,-73.98633" zoom="13" map-id="DEMO_MAP_ID">
            <div
                class="place-autocomplete-card"
                slot="control-inline-start-block-start">
                <gmp-place-autocomplete placeholder="Search for a place..."></gmp-place-autocomplete>
            </div>
        </gmp-map>
    </body>
</html>