Autosuggest Component (Leaflet)

A component taken from the what3words JavaScript Wrapper.

The JavaScript API wrapper provides components to make using the what3words API even easier. In this tutorial we will go through using the autosuggest component in combination with a Leaflet. We will add the search field using the component and then respond to its select event to place a pin on the map at the inputted location.

Step 1: Obtain an API key

Sign up to obtain your free API key.

Step 2: Installation

To load the what3words JavaScript API, use a script tag like the one in the following example:

<script src="https://assets.what3words.com/sdk/v3/what3words.js?key=YOUR_API_KEY"></script>

The URL contained in the script tag is the location of a JavaScript file that loads everything you need for using the what3words JavaScript API.

The key parameter contains your application's API key. Sign up to obtain your free API key.

Step 3: Usage

Using the autosuggest component

In one line you can have an input box which will call the what3words autosuggest API endpoint.

<what3words-autosuggest/>

Try it here:

There are a number of ways you can configure the autosuggest component to better suite your usecase, including clipping to country and custom validation errors.

For more on the autosuggest component see the what3words Autosuggest JavaScript Component.

Loading a map using leaflet

You'll need to give yourself access to the w3w autosuggest component and the style and js from leaflet.

<script src="https://assets.what3words.com/sdk/v3/what3words.js?key=YOUR_API_KEY"></script> 
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css"
   integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ=="
   crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"
   integrity="sha512-GffPMF3RvMeYyc1LWMHtK8EbPv0iNZ8/oTtHPx9/cc2ILxQ+u905qIwdpULaqDkyBKgOaB57QTMg7ztg8Jm2Og=="
   crossorigin=""></script> 

Place the map on the page, centered at a location of your chosing.

<div id='map'>
var map = L.map('map', {zoomControl: false}).setView([51.520847, -0.195521], 16);
  L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
      maxNativeZoom:19,
      maxZoom:25
  }).addTo(map);
});

Set the navigation contols.

var nav = new mapboxgl.NavigationControl();
map.addControl(nav, 'bottom-right');

Position the component on the map

Determine the position of the component on the map.

<style>
  #autosuggest {
    position: absolute;
    top: 10px;
    left: 10px;
    z-index: 9999;
  }
  #wrapper {
    position: relative;
    height: 100%;
  }
  #map {
    height: 400px;
    width: 100%;
  } 
  html, body {
    height: 100%;
    margin: 0;
    padding: 0;
    font-size: 12px;
  } 
</style>

Tie the component to the styling.

<div id="wrapper">
  <div id="autosuggest">
    <what3words-autosuggest id="autosuggest"/>
  </div>
</div>

Listen for the select event

Here we use an event listener to pick up when a user selects a three word address from the listed suggestions for their input. Here we output information to console for debugging purposes.

const input = document.getElementById("suggestComponent");
  input.addEventListener("select", (value) => {
    console.log("[EVENT:select]", value.detail);
  });
});

Use convert to coordinates to get the lat/lng of the address.

With the what3words API we can jump between the three word address and the coordinates that relate to it easily. Here we call the api with the three word address selected by the user.

what3words.api.convertToCoordinates(value.detail).then(function(response) {
    console.log("[convertToCoordinates]", response);
});

Use to coordinates gained for the conver to coordinates API call to place a pin on the map and focus on it

Now we have our coordinates we can place a what3words custom marker for our selected three word address on our map and focus the map on this location.

if (response.coordinates) {
    // Clear out the old markers.
    markers.forEach(function(marker) {
      marker.remove();
    });
    markers = []; 
    
    var marker = L.marker([response.coordinates.lat,response.coordinates.lng], {icon: w3wIcon}).addTo(map);

    // Create a marker for the location
    markers.push(marker); 

    // Center the map on that location, and zoom in on it to display the grid
    map.setView([response.coordinates.lat, response.coordinates.lng], 18);
  }
});

Step 4: Putting It All Together

The example below takes the concepts described above, and turns some of them into a complete example. Here we have a autosuggest component place on a map, where we are listening for the select event. We are then using the what3words JavaScript Wrapper's convert to coordinates functionality to get the coordinates for that address. With those coordinates we then refocus the map and drop a pin on the location selected.

<html>
   <head>
      <script src="https://assets.what3words.com/sdk/v3/what3words.js?key=YOUR_API_KEY"></script>
      <link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css"
          integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ=="
          crossorigin=""/>
      <script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"
          integrity="sha512-GffPMF3RvMeYyc1LWMHtK8EbPv0iNZ8/oTtHPx9/cc2ILxQ+u905qIwdpULaqDkyBKgOaB57QTMg7ztg8Jm2Og=="
          crossorigin=""></script> 
      <style>
          #autosuggest {
            position: absolute;
            top: 10px;
            left: 10px;
            z-index: 9999;
          }
          #wrapper {
            position: relative;
            height: 100%;
          }
          #map {
             height: 100%;
          } 
          html, body {
            height: 100%;
            margin: 0;
            padding: 0;
            font-size: 12px;
          } 
      </style>
   </head>
   <body>
      <div id="wrapper">
         <div id="map"></div>
         <div id ="autosuggest">
            <what3words-autosuggest id="suggestComponent"/>
         </div>
      </div>
      <script>
         var w3wIcon = L.icon({
             iconUrl: 'https://what3words.com/map/images/marker-18.png',
             iconSize:     [50, 50], // size of the icon
             iconAnchor:   [22, 94], // point of the icon which will correspond to marker's location
         });
          
         var map = L.map('map', {zoomControl: false}).setView([51.520847, -0.195521], 16);
               L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
                   attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
                   maxNativeZoom:19,
                   maxZoom:25
               }).addTo(map);
               new L.Control.Zoom({ position: 'bottomright' }).addTo(map);
               
               var markers = [];
               
               const input = document.getElementById("suggestComponent");
               input.addEventListener("select", (value) => {
                 console.log("[EVENT:select]", value.detail);
                 // Call the what3words Forward API to obtain the latitude and longitude of the three word address provided
                 what3words.api.convertToCoordinates(value.detail).then(function(response) {
                       console.log("[convertToCoordinates]", response);
                   if (response.coordinates) {
                     // Clear out the old markers.
                    markers.forEach(function(marker) {
                       marker.remove();
                     });
                     markers = []; 
                     
                     var marker = L.marker([response.coordinates.lat,         response.coordinates.lng], {icon: w3wIcon}).addTo(map);
               
                     // Create a marker for the location
                     markers.push(marker); 
               
                     // Center the map on that location, and zoom in on it to display the grid
                     map.setView([response.coordinates.lat, response.coordinates.lng], 18);
                   }
                 });    
               });
      </script>
   </body>
</html>