I am attempting to implement SmartyStreets API to validate an address: street, city, and state, through a form. I have implemented without AJAX implementation, but when I switch over to AJAX implementation. It does not work? I read up on the necessity to use JSONP, but I am not using AJAX to POST directly to the SmartyStreets API. Instead, I am posting to a PHP script that will validate. I plan to do other things such as cache the address request and validated address in the backend with the response. I have created a Domain Key to access the SmartyStreets API, but I think this still does not work due to the CORS policy.
This is my address validation form:
<div class="container">
<h2>Validate US address</h2>
<form role="form" id="myForm" action="post_without_curl2-INPUT.php" method="POST">
<div class="form-group">
<label for="street">street:</label>
<input type="text" class="form-control" id="street" name="street" placeholder="Enter street">
</div>
<div class="form-group">
<label for="city">city:</label>
<input type="text" class="form-control" id="city" name="city" placeholder="Enter city">
</div>
<div class="form-group">
<label for="state">state:</label>
<input type="text" class="form-control" id="state" name="state" placeholder="Enter state">
</div>
<!--<div class="checkbox">-->
<!--<label><input type="checkbox"> Remember me</label>-->
<!--</div>-->
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
<!-- the result of the search will be rendered inside this div -->
<div id="result"></div>
<script>
// Attach a submit handler to the form
$( "#myForm" ).submit(function( event ) {
console.log("Submit form");
// Stop form from submitting normally
event.preventDefault();
// Send the data using post
var posting = $.post( "post_without_curl2-INPUT.php", $( "#myForm" ).serialize() );
// Put the results in a div
posting.done(function( data ) {
var content = $( data ).find( "#content" );
$( "#result" ).empty().append( content );
});
});
</script>
This is my PHP script to AJAX POST my address to:
<?php
// Your authentication ID/token (obtained in your SmartyStreets account)
$authId = urlencode("authID");
$authToken = urlencode("authToken");
// Your input to the API...
$addresses = array(
array(
"street" => $_POST['street'],
"city" => $_POST['city'],
"state" => $_POST['state'],
"candidates" => 1
);
// LiveAddress API expects JSON input by default, but you could send XML
// if you set the Content-Type header to "text/xml".
$post = json_encode($addresses);
// Create the stream context (like metadata)
$context = stream_context_create(
array(
"http" => array(
"method" => "POST",
"header" => "Content-Type: application/x-www-form-urlencoded\r\n"
."Content-Length: ".strlen($post)."\r\n",
"content" => $post
)
)
);
// Do the request, and we'll time it just for kicks
$start = microtime(true);
$page = file_get_contents("https://api.smartystreets.com/street-address/?auth-id={$authId}&auth-token={$authToken}", false, $context);
$end = microtime(true);
//// Show results
echo "<pre>";
echo "<b>Round-trip time (including external latency):</b> ";
echo (($end - $start) * 1000)." ms<br><br><br>"; // Show result in milliseconds, not microseconds
print_r(json_decode($page));
echo "</pre>";
?>
Your problem is in this line of JavaScript in your client code:
var content = $( data ).find( "#content" );
It appears that you are trying to do a DOM descendant search on the data that the SmartyStreets API is returning. That will not work. What is returned from the API is raw JSON data. It will look like this:
[{"input_index":0,"candidate_index":0,"delivery_line_1":"1 Infinite Loop","last_line":"Cupertino CA 95014-2083","delivery_point_barcode":"950142083017","components":{"primary_number":"1","street_name":"Infinite","street_suffix":"Loop","city_name":"Cupertino","state_abbreviation":"CA","zipcode":"95014","plus4_code":"2083","delivery_point":"01","delivery_point_check_digit":"7"},"metadata":{"record_type":"S","zip_type":"Standard","county_fips":"06085","county_name":"Santa Clara","carrier_route":"C067","congressional_district":"18","rdi":"Commercial","elot_sequence":"0031","elot_sort":"A","latitude":37.33053,"longitude":-122.02887,"precision":"Zip9","time_zone":"Pacific","utc_offset":-8,"dst":true},"analysis":{"dpv_match_code":"Y","dpv_footnotes":"AABB","dpv_cmra":"N","dpv_vacant":"N","active":"Y"}}]
Or formatted with your print_r(json_decode($page));
command it will look like this:
Array
(
[0] => stdClass Object
(
[input_index] => 0
[candidate_index] => 0
[delivery_line_1] => 1 Infinite Loop
[last_line] => Cupertino CA 95014-2083
[delivery_point_barcode] => 950142083017
[components] => stdClass Object
(
[primary_number] => 1
[street_name] => Infinite
[street_suffix] => Loop
[city_name] => Cupertino
[state_abbreviation] => CA
[zipcode] => 95014
[plus4_code] => 2083
[delivery_point] => 01
[delivery_point_check_digit] => 7
)
[metadata] => stdClass Object
(
[record_type] => S
[zip_type] => Standard
[county_fips] => 06085
[county_name] => Santa Clara
[carrier_route] => C067
[congressional_district] => 18
[rdi] => Commercial
[elot_sequence] => 0031
[elot_sort] => A
[latitude] => 37.33053
[longitude] => -122.02887
[precision] => Zip9
[time_zone] => Pacific
[utc_offset] => -8
[dst] => 1
)
[analysis] => stdClass Object
(
[dpv_match_code] => Y
[dpv_footnotes] => AABB
[dpv_cmra] => N
[dpv_vacant] => N
[active] => Y
)
)
)
As you can see, this is not something that you can use the jQuery .find()
function on.
Your code is already working properly for what you are asking. Your form POSTs to the PHP script and returns a response from the SmartyStreets API.
Congratulations. Now you just need to handle the data that is returned.
Might I suggest that you start with changing this:
var content = $( data ).find( "#content" );
$( "#result" ).empty().append( content );
To this:
//var content = $( data ).find( "#content" );
$( "#result" ).empty().append( data );