How to Integrate DOTS Global Address Complete into Lightning Component (server side call)

September 2023
Salesforce.com_logo.svg
Introduction

In this post we’ll be highlighting the different steps required to get the DOTS Global Address Complete service up and running in a sales force lightning component. Lightning components are a quick and easy way to customize your Salesforce experience. They allow developers to create custom layouts and functionality for their users.  DOTS Global Address Complete is a perfect pairing for lightning components; it provides some heavy lifting in finding the intended address that a user enters without having to type out all the fields. Additionally, the DOTS Global Address Complete service provides validation for US addresses so you can get extra insight on the mailability of a user entered address. To follow along with this tutorial you will need the following:

  1. Basic familiarity with Apex classes, JS, HTML, and Salesforce lightning components
  2. A DOTS Global Address Complete License key. Sign up for a free trial here!
  3. Developer Access in Salesforce

What is Salesforce and why does it matter?

Salesforce is a massively popular cloud-based CRM solution. Salesforce is also extremely extensible which makes it a great pairing with Service Objects products. Additionally, DOTS Global Address Complete can help speed up filling address information. For example, if you have someone taking customer addresses over the phone, having DOTS AC fill in an address as a user types can help speed up data input.

Step 1: Add the Service Objects Endpoint to the Salesforce CSP Trusted Site List

The first step will be to add the Service Objects DOTS AC endpoint. This will ensure the lightning component can successfully call the Address Complete service. To do this select the “Setup” option under settings icon in the right hand corner.

In the search bar, search the text “CSP” and then select “CSP Trusted Sites”. On the resulting page select the “New Trusted Site” button. On the resulting page fill in the following information:

Then click “Save”

 

Note: If you are using a trial key, the Trusted Site URL should be trial.serviceobjects.com but if you are using a production key, the URL should be sws.serviceobjects.com. You can simply add both URLs at this point for the ease of integration when you transition from a trial to a production key.

 

Step 2: Creating the Lightning Component

For this step, head to the developer console. This can be accessed through the same settings menu that was used to add the CSP in the previous step.

From here, select File, New, and then Lightning Component. Give your lightning component a proper name and select ok.

Congrats! You’ve created a lightning component. Well sort of, lets add some code to the component so that we can being calling the service.

Step 3: Adding the Input Form with Aura Components

For this step, we’ll add some basic input fields and aura components that we’ll use to search for suggestions based on the user’s input, display suggestions to the user, and automatically fill in once a user has selected an address.  Feel free to copy the code below.

<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:lightningQuickAction" access="global" controller="GAC">
    
    <!-- Here we can initialize all the values we will want the DOTS Address Complete service to to populate -->
    <aura:attribute name="address1" type="string" default=""/>
    <aura:attribute name="city" type="string" default=""/>
    <aura:attribute name="state" type="string" default=""/>
    <aura:attribute name="zip" type="string" default=""/>
    <aura:attribute name="country" type="string" default=""/>
    
    <!-- This List will hold all the prediction values for the service. -->
    <aura:attribute name="predictions" type="List" default="[]"/>
    
    <h3>DOTS Global Address Complete Demo</h3>
    
    <!-- This will be the lighting input for our address1 field, when a user types into this field, the page will call the getAddressSuggestions method in the controller -->
    <lightning:input label="Address 1" 
                     name="address1"
                     aura:id="address1" 
                     value="{!v.address1}"
                     onchange="{!c.getAddressSuggestions}" />
    <br/>
    
    <!-- This will hold the predictions that the DOTS Address Complete Service Returns.  If a user selects an address, it will call the getSelectedDetails method of the controller -->
    <div class="suggestions">
        <aura:if isTrue="{!v.predictions.length > 0}"> 
            <ul class="city_predictions" style="z-index:99">
                <aura:iteration items="{!v.predictions}" var="prediction" indexVar="index">
                    <li class="slds-listbox__item">
                        <a class="predicted_address" onclick="{!c.getSelectedDetails}" data-row-index="{!index}">{!prediction.Prediction} - {!prediction.Extra}</a>
                    </li>
                </aura:iteration>
            </ul>  
        </aura:if>
    </div>
    
    <!-- These are the rest of the input fields that the service will fill in. This is just a starting point to demo the service. Please review the documentation for the service to determine which fields would be best for your applicaiton -->
    <!-- https://docs.serviceobjects.com/display/devguide/AC+-+Address+Response -->
    
    <div class="address-inputs">
        <lightning:input label="City"
                         name="city"
                         aura:id="city"
                         value="{!v.city}" 
                         style="z-index:-1"/>
        <br/>
        <lightning:input label="State"
                         name="state"
                         aura:id="state"
                         value="{!v.state}" />
        <br/>
        <lightning:input label="Zip Code"
                         name="zip"
                         aura:id="zip"
                         value="{!v.zip}" />
        <br/>
        <lightning:input label="Country"
                         name="country"
                         aura:id="country"
                         value="{!v.country}" />
    </div>
    
    <!--This would be a great spot to put in some extra elements that may do something with the autocompleted values. I.e. add a record to the crm, update an address etc -->
</aura:component>

Here’s a couple things to note about the front end component

  • At the top in the aura:component tag we define the controller as pointing to GAC. We will create this in a moment but this is where the call to the DOTS Global Address Complete service will take place. This will allow us to make the call to the DOTS AC service on the server side of Salesforce.
  • We define the attributes that will hold the address values from the service. On the lightning input tag for the address1 field. When this field changes, we’ll make it call our getAddressSuggestions function which we will create in the next step.
  • The aura:iteration element that we created will quickly and easily display any suggestions we find once the service has them to show. If a user clicks on any of those addresses, then the app will call the ‘getSelectedDetails” function which we will define.
  • In this example we don’t do anything with the filled in address and we have a small number of fields for the service to fill in: address1, city, state, postal code, and country. This would be great time to review our documentation for the service to see which fields it would make sense to use in your particular application.

 

Step 4: Adding the Javascript to handle Component Events

Now that the visual part of our lightning component is in place, we’ll add the javascript that will handle the functions we defined in the previous step. Below is the component controller code and the helper code that we’ll use.

DOTSGlobalAddressCompleteController.js

({
    
    //This function will return an array of predicted addresses based on the user input
    getAddressSuggestions : function(component, event, helper){
     
        var input = component.get('v.address1');
        
        //Only search for predictions if the input isn't null or empty
        if(Boolean(input)){           
        
        var params = {
          "input" : input
        } 
        
        //Call the getSuggestions function in the GAC controller. If there are predictions, we'll set the array of addresses returned to the v.predictions list in the component
        helper.callServer(component,"c.getSuggestions",function(response){
            var resp = JSON.parse(response);
            component.set('v.predictions',resp.Addresses);
        },params);
        }
        //If no predictions are returned, v.predictions will be set to an empty list
        else{
            component.set('v.predictions', []);
        }
     
    },
    
    //This function will get additional details about an address that a user clicks.
    getSelectedDetails : function(component, event, helper){ 
 
        var selectedItem = event.currentTarget;
        
        //Get the Index of the selected address so we know which one the user pixed.
        var index = selectedItem.getAttribute("data-row-index");
        
        //Pull back the user's selected address
        var selection = component.get('v.predictions')[index];
        
        
        var addressType = selection.AddressType;
        var placeid = selection.Id;
  
        var params = {
               "placeId" : placeid  
            } 
        
        //If the address type is BuildingNumber, then we'll call the getUnits method to return all the available units for an address
        if(addressType == "BuildingNumber"){
            
            helper.callServer(component,"c.getUnits",function(response){
            var buildingDetails = JSON.parse(response);            
            component.set('v.predictions', buildingDetails.Addresses);         
        }, params);
        }
     else
        {
            //If the user selected a regular address, then we'll call the getDetails function of the GAC controller which will get additional details about the users selected address
            helper.callServer(component,"c.getDetails",function(response){
                var placeDetails = JSON.parse(response);
                
                //This where we do the "autofill" and set the input form values to the values the service found on the use selected address
                component.set('v.address1',placeDetails.AddressInfos[0].Address1);
                component.set('v.city',placeDetails.AddressInfos[0].Locality);
                component.set('v.state',placeDetails.AddressInfos[0].AdminArea);
                component.set('v.zip',placeDetails.AddressInfos[0].PostalCode);
                component.set('v.country',placeDetails.AddressInfos[0].Country);
                
                //Set the predictions List to an Empty Array
                component.set('v.predictions',[]); 
            },params);
        }
    }
})

DOTSAddressCompleteHelper.js

({
    //This will call our GAC class that will make the actual call to the address complete web service. 
    callServer : function(component,method,callback,params) {
        var action = component.get(method);
        if (params) {        
            action.setParams(params);
        }

        action.setCallback(this,function(response) {            
            var state = response.getState();
            if (state === "SUCCESS") { 
                // pass returned value to callback function
                callback.call(this,response.getReturnValue());   
            } else if (state === "ERROR") {
                // generic error handler
                var errors = response.getError();
                if (errors) {
                    console.log("Errors", errors);
                    if (errors[0] && errors[0].message) {
                        throw new Error("Error" + errors[0].message);
                    }
                } else {
                    throw new Error("Unknown Error");
                }
            }
        });
        
        $A.enqueueAction(action);
    }
})

DOTSGlobalAddressComplete.css

.suggestions.THIS {
    z-index:1 !important;
    font-size: 15px;
    background-color: white;
    margin-top: -19px !important;
    border-radius: 5px;
    position: absolute;
    border-width: thin;
    border-color: #a9a0a0;
    border-style: solid;
    padding-left: 12px;
    padding-right: 12px;
}

.address-inputs.THIS{
    z-index:-50!important;
    
}

A couple things to note about the code above:

  • In the getAddressSuggestions function, we check the “v.address1” value to ensure we only call the service when the v.address1 value has any input to lookup. If there is input, the function will call the endpoint to get predicted addresses and then set the v.predictions value to the array of addresses that was returned
  • getSelectedDetails will either return all the units associated with an address if the building type is equal to “BuildingNumber” or it will call the operation to get the fully parsed out details of the user selected address from the DOTS Address Complete service. If the later occurs, the code will set the component values to be the parsed out and validated returns from the service.
  • The callServer function in the helper.js file will call the GAC class that makes the actual call to the DOTS Global Address Complete service. We’ll create the GAC class momentarily.
Step 5: Creating the apex class to make a server side call to the service

This is where we will create the server side apex class that will call out to the DOTS Global Address Complete service. To do this, head over to the developer console and select File, New, and then Apex Class.

Enter a name for the Apex class and select “OK”. We’re simply going to call ours GAC.  In the newly created Apex class, we’ll put the following code:

public class GAC {
@AuraEnabled
    //This function calls the "Predict" endpoint which will return a list of address suggestions based on the user input
    //Right now this function is biased towards USA address with the query option '&bl=USA' feel free to remove the location or add to it.
    public static string getSuggestions(String input) {
        String url = 'https://trial.serviceobjects.com/AC/Predict?id='+getKey()+'&q='+EncodingUtil.urlEncode(input, 'UTF-8')+'&bl=&al=&l=7&pl=en';
        String response = getResponse(url);
        return response;
    }
@AuraEnabled
    //This gets the detailed information about the address the user selected. This result will have the parsed out info from the service.
    public static string getDetails(String placeId) {
     String url = 'https://trial.serviceobjects.com/AC/Select?id='+getKey()+'&q=' + EncodingUtil.urlEncode(placeId, 'UTF-8');
        String response = getResponse(url);
        return response;
    }
@AuraEnabled
    //This function gets all the possible unit numbers for addresses that have multiple unit numbers
    public static string getUnits(String placeId) {
     String url = 'https://trial.serviceobjects.com/AC/Units?id='+getKey()+'&q=' + EncodingUtil.urlEncode(placeId, 'UTF-8') + '&bs=USA&al=&l=7&pl=en';
        String response = getResponse(url);
        return response;
    } 

    //Makes a Simple HTTP GET request
    public static string getResponse(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(); 
        return responseBody;
    }
 
    //Gets the LicenseKey for the service call
    public static string getKey(){
        string key = 'YourLicenseKeyHere';
        return key;
    }
}

Here’s a few things to keep in mind about this code.

  • getSuggestions will return a list of predicted addresses for the service. The current logic for this web service call only returns 7 addresses at a time and has no bias location. If you wish to bias the results toward a specific country, then adding  comma separated list of ISO3 codes to the “&bl=” parameter will bias the results towards a specific set of countries.
  • getDetails will return all the parsed out information about a single user selected address. It takes in the address ID as an input which is a value returned for each of the addresses in the getSuggestions function.
  • getUnits will return all the available unit numbers at a specific address that has multiple apartment or suite numbers
  • Finally, the getKey function will return the license key used in the class. Fill in your license key here!
  • Note: The calls to the salesforce server side will incure Salesforce API transactions; depending on your subscription this can be a limited number of API calls.
Step 6: Adding the New Component to a Lightning App

To start head back to setup page and search Lightning App Builder in the search bar as shown below

On the resulting page either select “New” to create a new page or Edit on one of the existing pages. For examples sake, we will just add a component to the existing home page.  In the Lightning App editor you should now see the component we just created under the “Custom” section of the list of components.

To add this to a current page, simply drag and drop it to an open pane in the component section and then click save! If you are creating a new page you will have to activate the page first. Now we’re ready to test out our new component!

 

Step 7: Receiving Address Suggestions

Now it is time to see the service in action! Head over to the page or app where the new component was added. We will use the Service Objects office address as an example:

Notice the text “4 Addresses” next to the first suggestion. This tells us that there are 4 unit numbers at this address to choose from. If we select any of the non-apartment addresses, the values on the form should be automatically filled out:

Viola! You now have a working DOTS Global Address Complete demo in your salesforce instance.

 

Troubleshooting Tips and Tricks

  • The Browser inspector is your friend! If something isn’t working quite right, don’t be scared to step through the JS we created and see what’s going on behind the scenes.
  • Don’t forget to review our documentation for the service; this will help you get the most out of the response and determine which fields in the service would be beneficial for you to use.
  • If you have any questions or want suggestions on how to make use of the service, feel free to email support@serviceobjects.com and we would be happy to help you get the most of your Service Objects Subscription
Closing

While it may take a small bit of work to get DOTS Global Address Complete integrated into your Salesforce instance, it is most definitely worth it! This product is a great user-friendly time save when entering address information into a CRM and can help your salesforce users get the most out of the product. Get your free trial key today and start using it in your Salesforce instance!

Thanks for following along in our tutorial!

Salesforce CRM and Service Objects APIs are a great pairing to enrich and validate your customer and lead data. You can get started by downloading our sample code and signing up for a free trial key for the Global Address Complete service. For further assistance integrating any of our Customer Data Validation services with a Salesforce workflow rule, feel free to contact one of experts at support@serviceobjects.com.

LAST MODIFIED DATE

About Service Objects

Founded in 2001, Service Objects is the leading provider of contact validation solutions, validating online transactions in real-time, including contact name, address, phone, email, and device. Using Service Objects’ global validation and location web services, businesses can identify potentially fraudulent contact records, append additional contact information, and process transactions in a more efficient manner. Service Objects has validated nearly 5 billion contacts, and major brands such as American Express, Microsoft, and Amazon rely on Service Objects for their data validation needs.

For more information about Service Objects’ real-time web services, contact sales@serviceobjects.com or visit us online at serviceobjects.com.

Tel. (805) 963-1700
Toll. (800) 694-6269
serviceobjects.com
136 West Canon Perdido St, Ste D
Santa Barbara, CA 93101-8207