1

I currently have a free account in SmartyStreets (aka Smarty) and need to integrate the autocomplete functionality. But after integrating the API using static values, it shows a CORS issue. Also, i have already tried the Access-Control-Allow-Origin but that also not working.

So my question is how to resolve the CORS issue?

Also, I have another question I would like to implement two other features.

  1. autocomplete addresses and populate values in the form.
  2. the page allows the user to type the address, send the request to SmartStreets, get the response, and display the result along with the form, empty this time, to allow the user to enter another address.

For More Details, please have a look at the below code:

Note: The Frontend code I am using is AngularJs with Typescript.

API Integration:
import { Injectable } from "@angular/core";
import { Observable } from "rxjs";
import { HttpClient, HttpParams } from "@angular/common/http";
@Injectable()
export class commonservice
{
    
    constructor(private httpclient:HttpClient){

    }
    getaddressauto(): Observable<any> {
       let smartauth = new HttpParams().set('auth-id',"72018252-ad10-b627-1234-970404bfd187");
       let smarttoken = new HttpParams().set('auth-token',"xuwSg95g4y8AObhEv3hx");
       let smartsearch = new HttpParams().set('search',"Louis");
       let smartcountry = new HttpParams().set('country',"FRA");
       return this.httpclient.get('https://international-autocomplete.api.smartystreets.com/lookup?'+smartauth+'&'+smarttoken+'&'+smartsearch+'&'+smartcountry) ;
    }
}
<html>
    <head>
        <title>SmartyStreets Address Verifier</title>
    </head>
    <body>
  <div class="p-field p-col-4">
                        <label for="address">Address Line 1</label>
                        <p-autoComplete [(ngModel)]="addressautocomplete2" [suggestions]="filteredGroup" (completeMethod)="filteraddressautocomplete($event)" (onSelect)="onEndUserSelect($event)" (onClear)="onEndUserSelect(null)" field="name" [minLength]="1" formControlName="EndUserAddressLine1">
                        </p-autoComplete>
                        <div *ngFor="let addressauto of addressautocomplete">
                            <p>{{addressauto.name}}</p>
                        </div>
                    
                    </div>
</body>
</html>
SunSparc
  • 1,812
  • 2
  • 23
  • 47

2 Answers2

4

You shouldn't be sending your auth-id and auth-token over the web. Use your embedded key instead.

When you use your embedded key don't forget to set the referrer header.

Smarty also has a javascript sdk that could simplify a lot of this stuff

3

Here is a JSFiddle that may be helpful. It seems to be what you want to accomplish as far as a call to Smarty US Autocomplete Pro, followed by a call to Smarty US Street, then filling a form with a result.

https://jsfiddle.net/x8eLpgm1/1/

$(function() {

  var menu = $(".us-autocomplete-pro-menu");
  var input = $("#us-autocomplete-pro-address-input");

  function getSuggestions(search, selected) {
    $.ajax({
      url: "https://us-autocomplete-pro.api.smartystreets.com/lookup?",
      data: {
        // Don't forget to replace the key value with your own embedded key 
        "key": "21102174564513388",
        "search": search,
        "selected": (selected ? selected : "")
      },
      success: function(data) {
        if (data.suggestions) {
          buildMenu(data.suggestions);
        } else {
          noSuggestions();
        }
      },
      error: function(error) {
        return error;
      }
    });
  }

  function getSingleAddressData(address) {
    $.ajax({
      url: "https://us-street.api.smartystreets.com/street-address?",
      data: {
        // Don't forget to replace the key value with your own embedded key
        "key": "21102174564513388",
        "street": address[0],
        "city": address[1],
        "state": address[2]
      },
      dataType: "jsonp",
      success: function(data) {
        $("#zip").val(data[0].components.zipcode);
        $("#data-lat").html(data[0].metadata.latitude);
        $("#data-lon").html(data[0].metadata.longitude);
        $("#data-county").html(data[0].metadata.county_name);
        $("#data-time-zone").html(data[0].metadata.time_zone);
      },
      error: function(error) {
        return error;
      }
    });
  }

  function clearAddressData() {
    $("#city").val("");
    $("#state").val("");
    $("#zip").val("");
    $("#data-lat").empty();
    $("#data-lon").empty();
    $("#data-county").empty();
    $("#data-time-zone").empty();
  }

  function noSuggestions() {
    var menu = $(".us-autocomplete-pro-menu");
    menu.empty();
    menu.append("<li class='ui-state-disabled'><div>No Suggestions Found</div></li>");
    menu.menu("refresh");
  }

  function buildAddress(suggestion) {
    var whiteSpace = "";
    if (suggestion.secondary || suggestion.entries > 1) {
      if (suggestion.entries > 1) {
        suggestion.secondary += " (" + suggestion.entries + " more entries)";
      }
      whiteSpace = " ";
    }
    var address = suggestion.street_line + whiteSpace + suggestion.secondary + " " + suggestion.city + ", " + suggestion.state + " " + suggestion.zipcode;
    var inputAddress = $("#us-autocomplete-pro-address-input").val();
    for (var i = 0; i < address.length; i++) {
      var theLettersMatch = typeof inputAddress[i] == "undefined" || address[i].toLowerCase() !== inputAddress[i].toLowerCase();
      if (theLettersMatch) {
        address = [address.slice(0, i), "<b>", address.slice(i)].join("");
        break;
      }
    }
    return address;
  }

  function buildMenu(suggestions) {
    var menu = $(".us-autocomplete-pro-menu");
    menu.empty();
    suggestions.map(function(suggestion) {
      var caret = (suggestion.entries > 1 ? "<span class=\"ui-menu-icon ui-icon ui-icon-caret-1-e\"></span>" : "");
      menu.append("<li><div data-address='" +
        suggestion.street_line + (suggestion.secondary ? " " + suggestion.secondary : "") + ";" +
        suggestion.city + ";" +
        suggestion.state + "'>" +
        caret +
        buildAddress(suggestion) + "</b></div></li>");
    });
    menu.menu("refresh");
  }

  $(".us-autocomplete-pro-menu").menu({
    select: function(event, ui) {
      var text = ui.item[0].innerText;
      var address = ui.item[0].childNodes[0].dataset.address.split(";");
      var searchForMoreEntriesText = new RegExp(/(?:\ more\ entries\))/);
      input.val(address[0]);
      $("#city").val(address[1]);
      $("#state").val(address[2]);

      if (text.search(searchForMoreEntriesText) == "-1") {
        $(".us-autocomplete-pro-menu").hide();
        getSingleAddressData(address);
      } else {
        $("#us-autocomplete-pro-address-input").val(address[0] + " ");
        var selected = text.replace(" more entries", "");
        selected = selected.replace(",", "");
        getSuggestions(address[0], selected);
      }
    }
  });

  $("#us-autocomplete-pro-address-input").keyup(function(event) {
    if (input.val().length > 0 || input.val() === "") clearAddressData();
    if (event.key === "ArrowDown") {
      menu.focus();
      menu.menu("focus", null, menu.menu().find(".ui-menu-item"));
    } else {
      var textInput = input.val();
      if (textInput) {
        menu.show();
        getSuggestions(textInput);
      } else {
        menu.hide();
      }
    }
  });

  $(".us-autocomplete-pro-menu").css("width", ($("#us-autocomplete-pro-address-input").width() + 24) + "px")

});
.us-autocomplete-pro-example {
  font-family: helvetica;
  color: #0a0a0a;
  text-align: center;
}

.us-autocomplete-pro-example .container {
  background-color: #ddd;
  padding: 2em;
}

.us-autocomplete-pro-example .container label {
  color: #0a0a0a;
}

.us-autocomplete-pro-example .container input {
  font-size: 16px;
  padding: 0 .75em;
  border: 1px solid #ccc;
  color: #0a0a0a;
  height: 3em;
  box-sizing: border-box;
  width: 100%;
  margin-top: .5em;
}

.us-autocomplete-pro-example .container input:disabled {
  background-color: #eee;
  color: #999;
}

.us-autocomplete-pro-example .container .us-autocomplete-pro-input-container {
  margin: 0 auto 2em;
  width: 60%;
}

.us-autocomplete-pro-example .container .us-autocomplete-pro-menu {
  overflow-y: scroll;
  max-height: 13em;
  box-shadow: 0 7px 7px rgba(0, 0, 0, 0.12);
  color: #7d7d7d;
  position: absolute;
  text-align: left;
  width: inherit;
  z-index: 10;
}

.us-autocomplete-pro-example .container .us-autocomplete-pro-menu li div {
  padding: .75em;
}

.us-autocomplete-pro-example .container .us-autocomplete-pro-menu b {
  color: #0a0a0a;
}

.us-autocomplete-pro-example .container .us-autocomplete-pro-menu .ui-menu-item-wrapper {
  padding-left: 1em;
}

.us-autocomplete-pro-example .container .labels {
  display: inline-block;
  font-weight: bold;
  width: 40%;
}

.us-autocomplete-pro-example .container .data {
  display: inline-block;
  padding-left: 1em;
  width: 50%;
}

.us-autocomplete-pro-example .docs-pricing-links {
  font-weight: bold;
  margin-top: 2em;
}

.inline {
  display: inline-block;
  vertical-align: top;
  width: 40%;
}

.data-container {
  text-align: center;
  margin-bottom: 2em;
}

.align-right {
  text-align: right;
}

.align-left {
  text-align: left;
}
<!DOCTYPE html>
<html lang="en">

  <head>
    <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
        <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.1/jquery-ui.js"></script>
  </head>

  <body>

    <div class="content-white us-autocomplete-pro-example">
      <h2>US Autocomplete Pro</h2>
      <div class="container">
        <div class="us-autocomplete-pro-input-container">
          <label for="us-autocomplete-pro-address-input">Start typing a street address and watch how fast we send you
            verified suggestions</label><br>
          <input id="us-autocomplete-pro-address-input" placeholder="Enter Address" autocomplete="smartystreets"/>
          <ul class="us-autocomplete-pro-menu" style="display:none;"></ul>
          <div class="disabled-inputs">
            <input id="city" placeholder="City" disabled />
            <div class="state-and-zip">
              <input id="state" placeholder="State" disabled />
              <input id="zip" placeholder="Zip*" disabled />
            </div>
          </div>
        </div>
        <div class="data-container">
          <div>
            <h3>*Additional Data</h3>
            <div class="labels inline align-right">
              <span>Latitude:</span><br>
              <span>Longitude:</span><br>
              <span>County:</span><br>
              <span>Time Zone:</span>
            </div>
            <div class="data inline align-left">
              <span id="data-lat"></span><br>
              <span id="data-lon"></span><br>
              <span id="data-county"></span><br>
              <span id="data-time-zone"></span>
            </div>
            <div class="more-data">
              ... along with 32 other points of data.
            </div>
          </div>
        </div>
        <div class="disclaimer">*ZIP Code & Additional Data retrieved from <a href="https://smartystreets.com/products/apis/us-street-api">US
            Street Address API</a></div>
      </div>

      <div class="docs-pricing-links">
        Pretty cool huh? You should see the <a href="https://smartystreets.com/docs/cloud/us-autocomplete-api#autocomplete-professional">Autocomplete
          Pro Docs</a> for more info
      </div>

    </div>

  </body>

</html>
Bryan Amundson
  • 131
  • 1
  • 6
  • 1
    I just realized that your question was for Smarty International Autocomplete whereas my answer was for US Autocomplete. We do not yet have a JSFiddle for International but you can check out the sample code in the Smarty Javascript SDK. Together, they can give you the direction you will need to build a solution. https://github.com/smarty/smartystreets-javascript-sdk/blob/master/examples/international_address_autocomplete.js – Bryan Amundson Jun 01 '22 at 16:06