Examples & Recipes
Practical examples and code patterns for common use cases with Places Autocomplete JS.
Quick Navigation
Auto-populate form fields from address
Dynamic Country FilteringUpdate region based on user selection
Geolocation BiasingPrioritize results near user's location
Multi-Step FormsManage instances across form steps
Error HandlingGracefully handle API errors
Distance-Based SearchShow distances from origin point
Visual CategorisationDisplay place type icons
Response TypeGet raw JSON or Place objects
Checkout Form Integration
Automatically populate form fields with structured address components from a selected place.
const autocomplete = new PlacesAutocomplete({
containerId: 'shipping-address',
googleMapsApiKey: 'YOUR_API_KEY',
fetchFields: ['formattedAddress', 'addressComponents'],
onResponse: (placeDetails) => {
// Populate form fields from address components
const components = placeDetails.addressComponents || [];
const getComponent = (type) => {
const comp = components.find(c => c.types.includes(type));
return comp ? comp.longText : '';
};
document.getElementById('street').value =
getComponent('street_number') + ' ' + getComponent('route');
document.getElementById('city').value = getComponent('locality');
document.getElementById('state').value =
getComponent('administrative_area_level_1');
document.getElementById('zip').value = getComponent('postal_code');
document.getElementById('country').value = getComponent('country');
},
options: {
placeholder: 'Enter shipping address...',
clear_input: false
}
});
Tip: Set clear_input: false to keep the
full address visible in the input field after selection.
Dynamic Country Filtering
Update the autocomplete region and language based on a country dropdown selection.
const countrySelect = document.getElementById('country-select');
const autocomplete = new PlacesAutocomplete({
containerId: 'autocomplete-container',
googleMapsApiKey: 'YOUR_API_KEY',
requestParams: {
includedRegionCodes: ['US']
}
});
// Update region when country changes
countrySelect.addEventListener('change', (e) => {
const countryCode = e.target.value;
autocomplete.setRequestParams({
includedRegionCodes: [countryCode],
region: countryCode,
language: getLanguageForCountry(countryCode)
});
autocomplete.clear();
});
function getLanguageForCountry(code) {
const languageMap = {
'US': 'en-US',
'GB': 'en-GB',
'FR': 'fr',
'DE': 'de',
'ES': 'es'
};
return languageMap[code] || 'en';
}
Note: Calling clear() after updating parameters
ensures a fresh session token is generated for the new region.
Geolocation Biasing
Use the browser's geolocation API to bias results toward the user's current location.
// Request user's current location
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
(position) => {
const userLocation = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
const autocomplete = new PlacesAutocomplete({
containerId: 'autocomplete-container',
googleMapsApiKey: 'YOUR_API_KEY',
requestParams: {
origin: userLocation,
locationBias: {
lat: 53.39670653190076,
lng: -2.9346197562747967,
radius: 50000 // 50km radius
}
},
options: {
distance: true,
distance_units: 'miles'
}
});
},
(error) => {
console.error('Geolocation error:', error);
// Initialise without location bias
new PlacesAutocomplete({
containerId: 'autocomplete-container',
googleMapsApiKey: 'YOUR_API_KEY'
});
}
);
}
Privacy: Always request user permission before accessing geolocation. Provide a fallback for users who deny permission.
Multi-Step Forms
Manage autocomplete instances across multiple form steps with proper cleanup.
let currentAutocomplete = null;
let formData = {
billingAddress: null,
shippingAddress: null
};
function initialiseStep(step) {
// Clean up previous instance
if (currentAutocomplete) {
currentAutocomplete.destroy();
}
const containerId = step === 1 ? 'billing-address' : 'shipping-address';
currentAutocomplete = new PlacesAutocomplete({
containerId: containerId,
googleMapsApiKey: 'YOUR_API_KEY',
onResponse: (placeDetails) => {
if (step === 1) {
formData.billingAddress = placeDetails;
} else {
formData.shippingAddress = placeDetails;
}
// Enable next button
document.getElementById('next-btn').disabled = false;
},
options: {
autofocus: true
}
});
}
// Initialize first step
initialiseStep(1);
// Handle step navigation
document.getElementById('next-btn').addEventListener('click', () => {
const currentStep = getCurrentStep();
if (currentStep === 1) {
showStep(2);
initialiseStep(2);
} else {
submitForm(formData);
}
});
Important: Always call destroy() before creating a new
instance to prevent memory leaks and event listener duplication.
Error Handling
Implement robust error handling with user-friendly messages for different error scenarios.
const autocomplete = new PlacesAutocomplete({
containerId: 'autocomplete-container',
googleMapsApiKey: 'YOUR_API_KEY',
onResponse: (placeDetails) => {
// Clear any previous errors
hideError();
// Validate the response
if (!placeDetails.addressComponents) {
showError('Unable to retrieve full address details. Please try again.');
return;
}
// Process the place details
processAddress(placeDetails);
},
onError: (error) => {
console.error('Autocomplete error:', error);
// Handle specific error types
if (error.message?.includes('ZERO_RESULTS')) {
showError('No results found. Please try a different search term.');
} else if (error.message?.includes('OVER_QUERY_LIMIT')) {
showError('Service temporarily unavailable. Please try again later.');
} else if (error.message?.includes('REQUEST_DENIED')) {
showError('Service configuration error. Please contact support.');
} else {
showError('An error occurred. Please try again.');
}
}
});
function showError(message) {
const errorDiv = document.getElementById('error-message');
errorDiv.textContent = message;
errorDiv.classList.remove('hidden');
}
function hideError() {
document.getElementById('error-message').classList.add('hidden');
}
Distance-Based Search
Display distances from a fixed origin point and optionally restrict search radius.
const autocomplete = new PlacesAutocomplete({
containerId: 'autocomplete-container',
googleMapsApiKey: 'YOUR_API_KEY',
requestParams: {
origin: { lat: 51.5074, lng: -0.1278 }, // London
// Optional: restrict to a specific radius
locationRestriction: {
lat: 51.5074,
lng: -0.1278,
radius: 100000 // 100km
}
},
options: {
distance: true,
distance_units: 'km'
},
onResponse: (placeDetails) => {
console.log('Selected place:', placeDetails);
// Distance is shown in the suggestions automatically
// You can also calculate your own distance if needed
if (placeDetails.location) {
const distance = calculateDistance(
{ lat: 51.5074, lng: -0.1278 },
placeDetails.location
);
console.log('Distance from London:', distance, 'km');
}
}
});
// Haversine formula for distance calculation
function calculateDistance(point1, point2) {
const R = 6371; // Earth's radius in km
const dLat = toRad(point2.lat - point1.lat);
const dLon = toRad(point2.lng - point1.lng);
const lat1 = toRad(point1.lat);
const lat2 = toRad(point2.lat);
const a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.sin(dLon/2) * Math.sin(dLon/2) *
Math.cos(lat1) * Math.cos(lat2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return R * c;
}
function toRad(degrees) {
return degrees * Math.PI / 180;
}
Note: Distance is automatically displayed in suggestions when origin is provided in
requestParams and options.distance is true.
Visual Categorisation
Display icons representing the place type (e.g., 🏪 Shopping, 🍽️ Dining) to help users identify places.
const autocomplete = new PlacesAutocomplete({
containerId: 'autocomplete-container',
googleMapsApiKey: 'YOUR_API_KEY',
options: {
show_place_type: true, // Enable place type icons (🏪, 🍽️, etc.)
placeholder: 'Search for places...'
}
});
Note: This option is mutually exclusive with distance: true.
Response Type
Choose between receiving a plain JSON object or a full Google Maps Place instance.
const autocomplete = new PlacesAutocomplete({
containerId: 'autocomplete-container',
googleMapsApiKey: 'YOUR_API_KEY',
options: {
response_type: 'place' // Get full Google Maps Place instance
},
onResponse: (place) => {
// 'place' is now a google.maps.places.Place instance
console.log('Place ID:', place.id);
// You can access all Place properties and methods
// Note: Some properties might need additional data fetching
if (place.location) {
map.setCenter(place.location);
}
}
});
Retain Input Value After Selection
Keep the selected address visible in the input field instead of clearing it.
const autocomplete = new PlacesAutocomplete({
containerId: 'autocomplete-container',
googleMapsApiKey: 'YOUR_API_KEY',
options: {
clear_input: false, // Keep the address in the input field
placeholder: 'Enter your address...'
},
onResponse: (placeDetails) => {
// The input field will now show the formattedAddress
console.log('Selected:', placeDetails.formattedAddress);
// You can still access the full details
console.log('Full details:', placeDetails);
}
});
Single Page Application (SPA) Integration
Properly manage component lifecycle in SPAs to prevent memory leaks.
// app.js or routing file
class AddressComponent {
constructor(containerId, apiKey) {
this.containerId = containerId;
this.apiKey = apiKey;
this.autocomplete = null;
}
mount() {
this.autocomplete = new PlacesAutocomplete({
containerId: this.containerId,
googleMapsApiKey: this.apiKey,
onResponse: (placeDetails) => {
this.handlePlaceSelection(placeDetails);
}
});
}
unmount() {
if (this.autocomplete) {
this.autocomplete.destroy();
this.autocomplete = null;
}
}
handlePlaceSelection(placeDetails) {
// Emit event or update state
this.onPlaceSelected?.(placeDetails);
}
}
// Usage with routing
const router = {
'/checkout': {
onEnter: () => {
const addressComponent = new AddressComponent(
'address-input',
'YOUR_API_KEY'
);
addressComponent.mount();
// Store reference for cleanup
window.currentComponents = { addressComponent };
},
onLeave: () => {
window.currentComponents?.addressComponent?.unmount();
}
}
};
Critical: Always clean up instances when navigating away from views to prevent memory leaks and duplicate event listeners.
More Examples
Check out additional working examples in the main examples section:
Checkout Form
Complete checkout form with address autocomplete
Restaurant & Store Finder
Filter searches by business type with rich place details
Delivery Address Validation
Validate delivery zones with distance-based pricing
Address Book Management
Save and manage multiple addresses with localStorage
Address Verification
Compare user input against Google data to detect errors
Distance Display
Show distance from a fixed origin point
Country Filtering
Dynamic region filtering based on country selection
Retain Input Value
Keep selected address in the input field