2

I am querying the zippopotam.us Zip Code lookup service to return City info. This stand alone code block works:

$("#studentPostCode").blur(function() {
  var zip_in = $(this);
  if (zip_in.val().length == 5) {
    $.ajax({
      url: "http://api.zippopotam.us/SE/" + zip_in.val(),
      cache: false,
      dataType: "json",
      type: "GET",
      success: function(result, success) {
        // Accept the first result
        var places0 = result['places'][0];
        var placeName = places0['place name'];
        $("#studentCity").val(placeName);
      },
      error: function(result, success) {}
    });
  }
});

However when I try to refactor so I can use it in other places, it breaks. My efforts:

//calls
$("#studentPostCode").blur(function() {
  var pCode0 = $(this);
  var myCity0 = getPlaceFromPostCode(pCode0);
  $("#studentCity").val(myCity0);
});

$("#guardian1PostCode").blur(function() {
  var pCode1 = $(this);
  var myCity1 = getPlaceFromPostCode(pCode1);
  $("#guardian1City").val(myCity1);
});

//function refactored as:
$(function getPlaceFromPostCode(pCodeX) {
  var zip_in = pCodeX;
  if (zip_in.val().length == 5) {
    $.ajax({
      url: "http://api.zippopotam.us/SE/" + zip_in.val(),
      cache: false,
      dataType: "json",
      type: "GET",
      success: function(result, success) {
        // Accept the first result
        var places0 = result['places'][0];
        var placeName = places0['place name'];
        return placeName;
      },
      error: function(result, success) {}
    });
  }
});

This returns "placeName" as undefined. Where am I going wrong?

thefourtheye
  • 233,700
  • 52
  • 457
  • 497
bsidey
  • 35
  • 2
  • 4
  • Can you show what Ajax returns? – Randy May 27 '16 at 06:14
  • Actually your `placeName` should return correct value as long as `zip_in.val()` is in [valid range](http://zippopotam.us/) of `10005 - 98499`. But your function will also not return `placeName` since you re running an asynchronous request. – choz May 27 '16 at 06:24
  • Possible duplicate of [How do I return the response from an asynchronous call?](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – JJJ May 27 '16 at 06:25

3 Answers3

0

If you want this to work, then you should add async: false in your $.ajax, because $.ajax is async, you are getting undefined. If you want it to be aysnc then you should go something with promise.

Mohith
  • 105
  • 3
  • That's really bad advice, and wouldn't even work because the function is still not returning anything. – JJJ May 27 '16 at 06:48
0

The return placeName; statement in the success handler is ignored, as the function itself is called asynchronously and the getPlaceFromPostCode method does not return anything. Try something along the lines of:

function getPlaceFromPostCode(pCodeX, cityCallback) {
  //... the $.ajax call
  success: function(result, success) {
    // Accept the first result
    var places0 = result['places'][0];
    var placeName = places0['place name'];
    cityCallback(placeName);
  }, //... etc
}

and then to call the function (there's probably an easier shorthand for this as well instead of a full-blown function):

getPlaceFromPostCode(pCode1, function(city){
  $("#guardian1City").val(city);
});
t6nn
  • 81
  • 3
0

Because the request takes some time to finish, it might make more sense to pass in the item that changes as a variable to the function, and then have the function use the data from the item to get the zip code and then later update the input box when the call is successful.

function updateInputByZipCode(inputElementToRead) {
  var zipCode = $(inputElementToRead).val();
  if (zipCode.length == 5) {
    $.ajax({
      url: "http://api.zippopotam.us/US/" + zipCode,
      cache: false,
      dataType: "json",
      type: "GET",
      success: function(result, success) {
        // Accept the first result
        var places0 = result['places'][0];
        var placeName = places0['place name'];
        $('#' + $(inputElementToRead).attr('output')).val(placeName);
      },
      error: function(result, success) {}
    });
  }
}

//calls
$("#studentPostCode, #guardianPostCode").blur(function() {
  updateInputByZipCode(this);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="studentPostCode" output="studentCity" value="32003"/>
<input id="guardianPostCode" output="guardianCity" value="10005"/><br>
<input id="studentCity"/>
<input id="guardianCity"/>
Moishe Lipsker
  • 2,974
  • 2
  • 21
  • 29