Source: https://developers.woosmap.com/products/localities/guides/map-js-guide/

> For clean Markdown of any page, append `.md` to the page URL.

> For a complete documentation index, see https://developers.woosmap.com/llms.txt

# Using Localities with the Map JS API



## Overview

The [`LocalitiesService` class](/products/map-api/reference/1.4/#woosmap.map.LocalitiesService) 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](/api-reference/authentication/) 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.

```html
<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](/products/map-api/get-started/) 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.

https://demo.woosmap.com/js-samples/samples/localities-autocomplete/app/dist/
[](https://demo.woosmap.com/js-samples/samples/localities-autocomplete/highlight/highlight.html "Open in new tab with highlighted code")
Try sample 

- [CodeSandbox](https://codesandbox.io/p/devbox/github/woosmap/js-samples/tree/master/dist/samples/localities-autocomplete/app?file=index.ts)
- [JsFiddle](https://jsfiddle.net/gh/get/library/pure/woosmap/js-samples/tree/master/dist/samples/localities-autocomplete/jsfiddle)
- [Clone on Github](https://github.com/Woosmap/js-samples/tree/sample/localities-autocomplete)

### Localities Autocomplete Request

To begin, create an instance of `woosmap.map.LocalitiesService` and call the `autocomplete()` method, passing it a [`LocalitiesAutocompleteRequest`](/products/map-api/reference/1.4/#woosmap.map.localities.LocalitiesAutocompleteRequest) object.

```plaintext
{
    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:

```javascript
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.

```plaintext
{
    publicId: string,
    language?: string,
    fields?: string,
    countryCodeFormat?: string,
}
```

Here is an example call:

```javascript
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.

https://demo.woosmap.com/js-samples/samples/localities-geocode/app/dist/
[](https://demo.woosmap.com/js-samples/samples/localities-geocode/highlight/highlight.html "Open in new tab with highlighted code")
Try sample 

- [CodeSandbox](https://codesandbox.io/p/devbox/github/woosmap/js-samples/tree/master/dist/samples/localities-geocode/app?file=index.ts)
- [JsFiddle](https://jsfiddle.net/gh/get/library/pure/woosmap/js-samples/tree/master/dist/samples/localities-geocode/jsfiddle)
- [Clone on Github](https://github.com/Woosmap/js-samples/tree/sample/localities-geocode)

### Request Localities Geocode

To make a request, call `LocalitiesService.geocode()` with a [`LocalitiesGeocodeRequest`](/products/map-api/reference/1.4/#woosmap.map.localities.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:

```javascript
const reverseGeocodeRequest = {
  latLng: { lat: 43.61, 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:

```javascript
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:

```typescript
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);
    });
  };
}
```

```javascript
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:

```javascript
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);
    }
  });
```
