3

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>";


?>
imparante
  • 503
  • 9
  • 21
  • 1
    no CORS issues if you are posting to your same domain with ajax and CORS isn't a problem server to server. What does current response look like? Use browser dev tools to inspect actual request if it is failing. double check auth method in api too – charlietfl Jul 26 '15 at 22:58
  • Okay, after following your advice I see that I needed to comment out the HTML output from the PHP script I was AJAX posting to. Now, I get Uncaught Error: Syntax error, unrecognized expression: Array. I get the json_decoded response in console.log, but jQuery:1496 doesn't like receiving the array... – imparante Jul 28 '15 at 07:44
  • can only send one echo and that is the json. Validate response from remote api also – charlietfl Jul 28 '15 at 10:26
  • Content-Type should also be `application/json`. – Michael Whatcott Jul 29 '15 at 21:40
  • @chaliefl I have set to send one json echo and there is a valid response from the remote api, but jQuery still gives me a Uncaught Error: Syntax error, unrecognized expression: (SmartyStreets JSON response) jQuery: 1496. – imparante Jul 30 '15 at 23:56
  • @mdwhatcott I have changed the Content-Typ to application/json, and getting the same jQuery: 1496 error - Uncaught Error: Syntax error, unrecognized expression: (SmartyStreets JSON response) – imparante Jul 30 '15 at 23:59

1 Answers1

1

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 );
SunSparc
  • 1,812
  • 2
  • 23
  • 47