-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathindex.ts
More file actions
148 lines (120 loc) · 4.66 KB
/
index.ts
File metadata and controls
148 lines (120 loc) · 4.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/**
* @license
* Copyright 2025 Google LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
// [START maps_place_autocomplete_data_session]
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();
// [END maps_place_autocomplete_data_session]