Part-7 Google Maps in LWC

Lets write a Lightning Web Component(LWC) that gives us a search bar with auto complete suggestions of Places around us using Google Maps / Place API Integration with Salesforce.

Actually, We are definitely not going see anything new today..! There are plenty of excellent articles already in google about google Maps integration with salesforce. We are just going to see how to construct the LWC version of such a search bar component.

Courtesy of Search Bar component
1. Visualforce Version : BenEdwards44
2. Aura Version : iamsonal
3. LWC Version : Current Page ( 😛 ) source code

Ook!, let Start,
firstly, we need some kind of search bar on the screen that act like an text-box as well as a drop-down, so How do we write the mark-up for that on lighting page with same styling? Its quite simple! there is some component called Combo-box for this purpose, just borrow the code from official SLDS site… click here

But again, do we need to write and maintain all the styling for the behavior of combo-box from scratch…?

The easiest way is to inspire from code written by pozil for custom combo-box component.(source code is here, BTW thank! pozil)

Now we just need to derive the Address Predictions from the search key that we have entered in the combo-box.

In order to get those predictions, we need to pass this search key to google place api., and get back the bunch of address predictions.


The above figure shows the project structure… Lets figure out each what each file does.

There are 2 Lightning Web Components in the above project ( source_code )

1. Lookup  – This component is like a supporting child component to advancedMapLookup.
2. AdvancedMapLookup – This component contains search-box and a button… to fire an event if needed.

There are 3 Apex class in the above project

1. AddressSearchController – Makes a REST API callout to google place api
2. LookupSearchResult – This class is like a supporting the
AddressSearchController class to build the object to pass later to search bar
3. PlaceFinder – This is also supporting a class to AddressSearchController to parse / extract address predictions received from google.

NOTE : Dont forget to add remote site settings record to make a callout to google APIs
endpoint : https://maps.googleapis.com

Lets discuss few important code snippets over here… remaining class and components are placed here

advancedMapLookup.html

The Below component has a Lookup child component and a button.

  1. Whenever we start typing in the lookup component handlesearch event can be fired.
  2. Whenever we select a suggestion or remove a suggestion handleSelectionChange can be called.
  3. For other specifications of c-lookup component please refer pozil’s repository… here
<template>
  <lightning-card title="Google Maps Integration (Lightning Web Component)">
    <div class="slds-form slds-form_stacked slds-m-around_xx-large">
      <c-lookup
        errors={errors}
        onsearch={handleSearch}
        onselectionchange={handleSelectionChange}
        label="Search"
        placeholder="Search Places"
      >
      </c-lookup>

      <lightning-button
        variant="brand"
        label="Submit"
        onclick={handleSubmit}
      ></lightning-button>
    </div>
  </lightning-card>
</template>

AddressSearchController.cls

  1. placeSearch method receives searchKey from advancedMapLookup.js
  2. Then, it makes a callout using using the api getKey() , dont forget to place your key in the key attribute
  3. Then, predictions are extracted with help of PlaceFinder class.
  4. Then, we create a payload to pass to search bar / combo-box in the way it expects using LookupSearchResult class.
public with sharing class AddressSearchController {

  @AuraEnabled(cacheable=true)
  public static List<LookupSearchResult> placeSearch(String searchPhrase) {
    System.debug('#### Called! ' + searchPhrase);
    String url =
      'https://maps.googleapis.com/maps/api/place/autocomplete/json?' +
      'input=' +
      EncodingUtil.urlEncode(searchPhrase, 'UTF-8') +
      '&types=geocode' +
      getKey();
    list<LookupSearchResult> results = new List<LookupSearchResult>();

    List<PlaceFinder.Address> sugg = getPlaceId(url);
    for (PlaceFinder.Address s : sugg) {
      results.add(
        new LookupSearchResult(
          s.placeId,
          '',
          'custom:custom106',
          s.description,
          ''
        )
      );
    }
    return results;
  }

  public static List<PlaceFinder.Address> getPlaceId(string strURL) {
    Http h = new Http();
    HttpRequest req = new HttpRequest();
    HttpResponse res = new HttpResponse();
    req.setMethod('GET');
    req.setEndpoint(strURL);
    req.setTimeout(120000);
    res = h.send(req);
    String responseBody = res.getBody();
    List<PlaceFinder.Address> aList = PlaceFinder.parse(responseBody);
    for (PlaceFinder.Address a : aList) {
      System.debug('@@@' + a);
    }
    return aList;
  }

  public static string getKey() {
    string key = 'PLEASE_PASTE_YOUR_API_KEY_FROM_GOOGLE_PLACE_API_WEBSITE';
    string output = '&key=' + key;
    return output;
  }
}

I think we have discussed the important code snippets.. the whole source code is in this repository you can place your google place api key and directly deploy into your scratch org.

Happy Learning!

In the next article we will enhance this component with another subsequent call-out to get coordinates of selected place in the search-box drop-down.

Then, we will use publish-subscribe pattern to mark the coordinates in the sibling map component.

Leave a Reply

Your email address will not be published. Required fields are marked *