0

I have been trying to return the value of 'city' variable but i keep geeting weird results, i know there must be something wrong with my code, i hope you can help me figure out what it is.

function getCity(lat,lng)
{
var url="http://maps.googleapis.com/maps/api/geocode/json?latlng=";
var sensor="&sensor=false";

var city;
$.getJSON(url+lat+","+lng+sensor,function(json)
    {
        var address=json.results[0].address_components;
        var addr;
        for(var i in address)
            {
                addr=address[i];
                if(addr.types[0] == "locality" && addr.types[1] == "political")
                {
                    city=addr.long_name;

                }
            }
      });
      return city;
}
6
  • There is an error before your first return city. I think it should read city = addr.long_name - you're missing the = . Commented Jul 19, 2013 at 2:31
  • 1
    Please post the JSON string sent by the server, and an example of your 'weird' results. Commented Jul 19, 2013 at 2:32
  • I think you should return immediately the value when your condition is satisfied. You don't need to wait to finish the loop. Commented Jul 19, 2013 at 2:33
  • 3
    I think getcity can not return you exact result, because its asynchronous call (ajax), which will have result later... so you should pass callback which will perform operation... Commented Jul 19, 2013 at 2:35
  • @Mike W : There is nothing wrong with my JSON, i use console.log(city); next to city=addr.long_name; and i get the correct value. Commented Jul 19, 2013 at 2:40

4 Answers 4

3

$.getJson is an async function, which means you are returning the city, then the success function is executed (if the call worked). What you want is to wait for the call to come back. Here's what I think is a nice way of doing this, using jquery deferred :

function getCity(lat,lng)
{
  var def = jQuery.Deferred(); 
var url="http://maps.googleapis.com/maps/api/geocode/json?latlng="
var sensor="&sensor=false";

var city;
$.getJSON(url+lat+","+lng+sensor,function(json)
    {
        var address=json.results[0].address_components;
        var addr;
        for(var i in address)
            {
                addr=address[i];
                if(addr.types[0] == "locality" && addr.types[1] == "political")
                {
                    city=addr.long_name;

                }
            }
        def.resolve(city);

      });
return def.promise();
}

$.when(getCity(40.714623,-74.006605)).then(function (city) {
 alert(city);   
});

Fiddle

Sign up to request clarification or add additional context in comments.

5 Comments

Deferred/Promise is baked in jQuery's ajax function. You don't need to create and resolve your own Deferred object.
@Phil-R: Working fine on Fiddlebut my firebug returns this error: TypeError: jQuery.Deferred is not a constructor var def = new jQuery.Deferred(); Any suggestion?
try var def = jQuery.Deferred(); without new
Yep, my bad, just do it without the new. I'll edit the post and fiddle.
Both Expressions are working i just had an old version of jquery, it's working know thank you all.
1

getcity is using asynchronous call (getJSON), which will have result later... so you should pass callback which will perform operation

another option is use synchronous call

$.ajax({
  url: myUrl,
  dataType: 'json',
  async: false,
  data: myData,
  success: function(data) {
    //stuff
  }
});

but still i feel , you should not wait for result, because browser will be hanged till result ... so go with call back approach...

Comments

1

getJSON is an asynchronous call. So you can't return a value from your getCity like a usual function. In your case city will be returned BEFORE getJSON returns any value. You need to work inside the callback function to use return value.

But you can take advantage of jQuery's deferred/promise so you don't need go deep into callback functions. You can try the code below;

function getCity(lat,lng) {
    var url="http://maps.googleapis.com/maps/api/geocode/json?latlng=";
    var sensor="&sensor=false";

    return $.getJSON(url+lat+","+lng+sensor);
}

function onSuccess(json) {
    var address=json.results[0].address_components;
    var addr;
    var city;

    for(var i in address) {
        addr=address[i];
        if(addr.types[0] == "locality" && addr.types[1] == "political") {
            city=addr.long_name;
        }
    }

    // And do other stuff
}

function onfail() {
    // Do something if there is a server error with the getJSON
}

getCity(lat, lng).done(onSuccess).fail(onfail);

Comments

0

Don't return city in your callback. Just assign it like this: city = addr.long_name;

Since it's still within the getCity scope it should return right.

Update

Change the way you request the data. Do it like this:

 $.getJSON(url+lat+","+lng+sensor).done(function(json){

           //Do your assignment here
 });

This is because it's an asynchronous call so you want it assigned after it's done.

1 Comment

I tried that but i get this error, TypeError: $.getJSON(...).done is not a function Please try to correct it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.