Using Localities with the Map JS API
A comprehensive guide to using the Localities API (Autocomplete, Details, and Geocoding) through the Woosmap Map JS’s LocalitiesService.
- Overview
- Getting Started
- Localities Autocomplete and Details
- Geocoding and Reverse Geocoding
- Best Practices
Overview
The LocalitiesService
class is the primary and recommended way to
interact with the Woosmap Localities API directly from the Map JS API. It provides a straightforward, promise-based
interface for the main Localities functionalities, including:
- Localities Autocomplete: Search for addresses and places as the user types.
- Localities Details: Get rich, detailed information for a specific locality.
- Localities Geocode: Convert addresses to geographic coordinates (geocoding) and coordinates to addresses (reverse geocoding).
This guide covers how to use each of these features.
Getting Started
Before using the LocalitiesService
, you must have a secure and valid Woosmap API key with the
Localities API enabled.
Next, load the Map JS API library by including the following script tag in your HTML page, replacing YOUR_API_KEY
with
your key.
<script async
src="https://sdk.woosmap.com/map/map.js?key=YOUR_API_KEY&callback=initMap">
</script>
For more details, see the Get Started with Map JS API guide.
Localities Autocomplete and Details
This feature allows you to implement a search box that provides address predictions as a user types and then retrieve full details for a selected prediction.
Localities Autocomplete Request
To begin, create an instance of woosmap.map.LocalitiesService
and call the autocomplete()
method, passing it a
LocalitiesAutocompleteRequest
object.
{
input: string,
components?: woosmap.map.localities.LocalitiesComponentRestrictions,
customDescription?: string,
data?: woosmap.map.localities.LocalitiesRequestData,
extended?: string,
language?: string,
location?: woosmap.map.LatLng | woosmap.map.LatLngLiteral,
radius?: number,
types?: string | string[],
}
A typical request looks like this:
const autocompleteRequest = {
input: "10 downing street",
types: ["locality", "address"],
language: "EN",
components: {country: ["GB"]},
};
const localitiesService = new woosmap.map.LocalitiesService();
localitiesService
.autocomplete(autocompleteRequest)
.then((response) => {
// response.localities contains an array of predictions
console.log(response.localities);
})
.catch((error) => console.error(error));
Localities Autocomplete Response
A successful autocomplete()
call returns a promise that resolves with a LocalitiesAutocompleteResponse
object, which
contains an array of LocalitiesPredictions
in the localities
field. Each prediction contains a description
and a
unique public_id
used to fetch more details.
Localities Details Request
To get full details for a selected prediction, use the getDetails()
method, passing the public_id
from the
autocomplete response.
{
publicId: string,
language?: string,
fields?: string,
countryCodeFormat?: string,
}
Here is an example call:
const detailsRequest = {
publicId: "aGVyZTphZjpzdHJlZXRzZWN0aW9uOlpWN1NSWDhMUlNlRVpWU3hQMUhFREQ6Q2dnSUJDRHd5c25UQWhBQkdnSXhNQQ", // public_id for "10 Downing Street"
language: "fr",
};
const localitiesService = new woosmap.map.LocalitiesService();
localitiesService
.getDetails(detailsRequest)
.then((response) => {
// response.result contains the full address details
console.log(response.result);
})
.catch((error) => console.error(error));
Localities Details Response
A successful getDetails()
call returns a LocalitiesDetailsResponse
object whose result
field contains detailed
information, including formatted_address
, geometry
, and address_components
.
Geocoding and Reverse Geocoding
The geocode()
method allows you to translate addresses into coordinates and vice-versa.
Request Localities Geocode
To make a request, call LocalitiesService.geocode()
with a
LocalitiesGeocodeRequest
object. You must provide either an address
for geocoding or a latLng
for reverse geocoding.
Below is an example of a reverse geocoding request:
const reverseGeocodeRequest = {
latLng: {lat: 43.610, lng: 3.876},
language: "fr",
components: {country: ["FR"]},
};
const localitiesService = new woosmap.map.LocalitiesService();
localitiesService
.geocode(reverseGeocodeRequest)
.then((response) => {
// response.results contains an array of matching addresses
console.log(response.results);
})
.catch((error) => console.error(error));
To perform a forward geocoding request, simply provide an address string:
const geocodeRequest = {
address: "24 Rue de la Paix, Paris, France",
};
// ...then call localitiesService.geocode(geocodeRequest)
Localities Geocode Response
A successful geocode()
call returns a LocalitiesGeocodeResponse
object. Its results
field contains an array of
localities, each with the same structure as a LocalitiesDetailsResponse
result, including formatted_address
,
geometry
, and address_components
.
Best Practices
Debouncing Autocomplete Requests
To manage API usage and prevent race conditions where responses return out of order, it is recommended to “debounce” your autocomplete requests. This ensures an API call is only made after the user has stopped typing for a brief period.
Here is a generic function to debounce any promise-based function:
type DebouncePromiseFunction<T, Args extends any[]> = (
...args: Args
) => Promise<T>;
function debouncePromise<T, Args extends any[]>(
fn: (...args: Args) => Promise<T>,
delay: number,
): DebouncePromiseFunction<T, Args> {
let timeoutId: ReturnType<typeof setTimeout> | null = null;
let latestResolve: ((value: T | PromiseLike<T>) => void) | null = null;
let latestReject: ((reason?: any) => void) | null = null;
return function (...args: Args): Promise<T> {
return new Promise<T>((resolve, reject) => {
if (timeoutId !== null) {
clearTimeout(timeoutId);
}
latestResolve = resolve;
latestReject = reject;
timeoutId = setTimeout(() => {
fn(...args)
.then((result) => {
if (latestResolve === resolve && latestReject === reject) {
resolve(result);
}
})
.catch((error) => {
if (latestResolve === resolve && latestReject === reject) {
reject(error);
}
});
}, delay);
});
};
}
function debouncePromise(fn, delay) {
let timeoutId = null;
let latestResolve = null;
let latestReject = null;
return function (...args) {
return new Promise((resolve, reject) => {
if (timeoutId !== null) {
clearTimeout(timeoutId);
}
latestResolve = resolve;
latestReject = reject;
timeoutId = setTimeout(() => {
fn(...args)
.then((result) => {
if (latestResolve === resolve && latestReject === reject) {
resolve(result);
}
})
.catch((error) => {
if (latestResolve === resolve && latestReject === reject) {
reject(error);
}
});
}, delay);
});
};
}
You can then apply it to the autocomplete
method:
const localitiesService = new woosmap.map.LocalitiesService();
// Debounce autocomplete request for 200ms
const debouncedAutocomplete = debouncePromise(localitiesService.autocomplete, 200);
debouncedAutocomplete(autocompleteRequest)
.then((response) => {
console.log(response.localities);
})
.catch((error) => {
if (error.name !== 'DebouncePromise') { // Ignore debounce cancellations
console.error(error);
}
});