Work with Localities
Use the LocalitiesService
to autocomplete and get details of localities, postal codes or addresses.
Overview
The LocalitiesService class
provides
methods for using the Localities API through Woosmap Map JavaScript API. It supports modern usage patterns such as
Promises.
This guide focus on the following supported operations from Localities:
- Localities Autocomplete lets you search for addresses data using text query.
- Localities Details provides details of an autocompleted address.
Review the example below to understand how to use autocomplete and get addresses details from Localities API using through Woosmap Map JS API:
Getting started
Before using the Localities service in the Map JavaScript API, it is required to have a secure and valid Woosmap API key and enable the Localities API for it.
Next, you must load the Map JS API library by including a script tag in your HTML page as follows:
<script async
src="https://sdk.woosmap.com/map/map.js?key=YOUR_API_KEY&callback=initMap">
</script>
See the Get Started with Map JS API guide for more information.
Localities Autocomplete
You can call this endpoint by first creating a new instance of
the woosmap.map.LocalitiesService
class and then call the dedicated method.
Localities Autocomplete Request
To initiate a request to Localities Autocomplete in the Woosmap Map JS API, create an object of
type woosmap.map.LocalitiesService
and call LocalitiesService.autocomplete()
,passing it
a LocalitiesAutocompleteRequest
object literal.
The LocalitiesAutocompletesRequest
object literal contains the following fields:
{
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[],
}
The fields are:
input
specifies the user entered input string.components
(optional) used to filter over countries. Countries must be passed as an ISO 3166-1 Alpha-2 or Alpha-3 compatible country code.customDescription
(optional) specifies the description format for all or some of the suggestion types selected. see how to build your custom description.data
(optional) opens suggestions to worldwide postal codes in addition to postal codes for Western Europe.extended
(optional) allows a refined search over locality names that bears the same postal code. possible value isextended=postal_code
language
(optional) specifies the language code, using ISO 3166-1 Alpha-2 country codes, indicating in which language the results should be returned, if possible. If language is not supplied, the Localities service will use english as default language. No language necessary for postal_code request.location
(optional) specifies the location for prediction biasing. The location defines the point around which to retrieve predictions in priority.radius
(optional) specifies the distance (in meters) within which to return place results. The maximum allowed radius is 100 000 meters. The default radius is 100 000 meters.types
(optional) specifies the types of predictions to be returned. By default, suggestions return typeslocality
andpostal_code
. can be either a single type or a list of LocalitiesTypes.
Below is a sample LocalitiesAutocompletesRequest
:
const autocompleteRequest = {
input: "10 downing street",
types: ["locality", "address"],
language: "EN",
components: {country: ["GB"]},
customDescription: "name,admin_1,admin_0",
radius: 500000,
location: {lat: 51.5007, lng: -0.1246},
};
The LocalitiesService
’s autocomplete()
method is asynchronous and returns
a Promise object that is
either fulfilled with an array
of LocalitiesPredictions
objects or
rejected with
an APIError
object. You can attach handlers to this Promise object to process results upon operation success or
failure.
const localitiesService = new woosmap.map.LocalitiesService();
localitiesService
.autocomplete(autocompleteRequest)
.then((response) => {
console.log(response.result);
})
.catch((error) => {
console.log(error);
})
.finally(() => {
console.log("done");
});
Localities Autocomplete Response
A successful autocomplete()
call returns a LocalitiesAutocompleteResponse
object with a localities[]
field, which
is an array
of LocalitiesPredictions
objects.
Each LocalitiesPredictions
object may contain the following fields:
{
localities[]: {
description: string,
public_id: string,
type?: string,
matched_substrings[]?: {
description[]:{
offset: number,
length: number
}
},
has_addresses?: boolean,
}
}
description
: A combination ofname
,admin_1
,admin_0
or requested customDescription. The content varies based on the requested type.public_id
: A unique identifier for the locality. To retrieve information about the locality, pass this identifier in the Localities Details request.has_addresses
(optional): A boolean indicating if the postal code has addresses. This field is only returned for thepostal_code
type in the United Kingdom.matched_substrings
(optional): An array of matched substrings for each field that matches elements in the input. Useful for highlighting these substrings.type
(optional): The type of the prediction, such aslocality
,address
, orpostal_code
.
Localities Details
Localities Details Request
The getDetails()
method from woosmap.map.LocalitiesService
is used to get details of a selected locality.
It also returns a Promise object that resolves to a LocalitiesDetailsResponse
object.
The LocalitiesDetailsRequest
object literal contains the following fields:
{
publicId: string,
language?: string,
fields?: string,
countryCodeFormat?: string,
}
publicId
: A textual identifier that uniquely identifies a locality, returned from aLocalitiesService.autocomplete()
.language
(optional): The language code, using ISO 3166-1 Alpha-2 country codes, indicating in which language the results should be returned, if possible. If language is not supplied, the Localities service will use english as default language. No language necessary for postal_code request.fields
(optional): Used to limit the returning fields whentype=address
. by default, and for other types localities, all fields are return. Only one field is available:geometry
.countryCodeFormat
(optional): To specify the format for the short country code expected to be returned in theaddress_components
field. Default is the format used to specify components or alpha2 if no components are specified.
Below is a sample call to LocalitiesServices.getDetails()
method passing the resulted publicId
from the above call
to LocalitiesServices.autocomplete()
(“10 Downing Street”).
const detailsRequest = {
publicId: "aGVyZTphZjpzdHJlZXRzZWN0aW9uOlpWN1NSWDhMUlNlRVpWU3hQMUhFREQ6Q2dnSUJDRHd5c25UQWhBQkdnSXhNQQ",
language: "fr",
};
const localitiesService = new woosmap.map.LocalitiesService();
localitiesService
.getDetails(detailsRequest)
.then((response) => {
console.log(response.result);
})
.catch((error) => {
console.log(error);
})
.finally(() => {
console.log("done");
});
Localities Details Response
A successful getDetails()
call returns a LocalitiesDetailsResponse
object with a result
field, which may contain
the following fields:
{
result: {
formatted_address: string,
public_id: string,
types[]: woosmap.map.localities.LocalitiesTypes,
geometry[]?: {
accuracy: woosmap.map.localities.LocalitiesDetailsAccuracy,
location: woosmap.map.LatLngLiteral,
viewport: woosmap.map.LatLngBoundsLiteral,
},
name?: string,
status?: string,
address_components[]?: {
long_name: string,
short_name: string,
types[]: string,
},
}
}
formatted_address
: Contains the readable text description of the result.public_id
: Contains a unique ID for the detailed locality.types
: Available locality types, represented as an array of LocalitiesTypes.geometry
: The location of the result, in latitude and longitude, eventually associated with a Viewport. Accuracy is also provided for locality of typeaddress
.name
: The postal code name if locality is of type postal_code.status
: This optional field is only available for UK addresses referenced asnot_yet_built
.address_components
: An array containing Address Components with additional information.
Debouncing Autocomplete Promise
Autocomplete is designed to support real-time, as-you-type search, processing requests for each keystroke to deliver instantaneous feedback. However, there are situations where the continuous as-you-type functionality may lead to unwanted behaviors.
-
If you want control over search operations usage, you may prefer to wait until the user stops typing before triggering an autocomplete request. Similarly, as Localities is a rate-limited services, sending too many requests from a lot of users in a short time can lead to API errors. In such cases, debouncing your sources with waiting time can help limit the number of requests triggered by Autocomplete.
-
If a later call takes less time than a previous one, it could potentially resolve before the previous one, leading to out-of-order execution. This is a common issue with asynchronous operations like promises.
To handle this, you can debounce your promise and implement a mechanism to ignore the results of all previous promises when a new one is created.
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);
});
};
}
Finally, you can use this debouncePromise()
function to debounce autocomplete request as follows:
const localitiesService = new woosmap.map.LocalitiesService();
// Debounce autocomplete request for 10ms
const debouncedLocalitiesAutocomplete = debouncePromise(localitiesService.autocomplete, 10);
debouncedLocalitiesAutocomplete(autocompleteRequest)
.then((response) => {
console.log(response.result);
})
.catch((error) => {
console.log(error);
})
.finally(() => {
console.log("done");
});