Ipad
Ipad

Reputation: 392

ajax call returns value but variable is null

I am trying to get a weather forecast from here. This is working fine and I get my value. If I do a normal ajax call it is working fine.

But:

function Weather() {
    var self = this,
        weatherUrl = 'http://api.openweathermap.org/data/2.5/weather?id=',
        value = null;

    function getWeatherForCity(id) {
        $.ajax({
            url: weatherUrl + id,
            async: false,
            success: function (data) {
                console.log(data);
                value = data;
            }
        });
    }

    self.getWeatherForCity = function (id) {
        var cast = value;
        console.log(cast);
        return cast;

    };
}

The call:

        weather = new Weather();

        console.log(weather.getWeatherForCity('2878234'));

If I debug through those functions, I get the good result inside of the success callback function, but cast variable is null, like it was never touched?

Could someone explain that to me?

Upvotes: 1

Views: 1346

Answers (3)

yesman
yesman

Reputation: 7829

You could also look into the $.when method, which waits for an Ajax call to complete before proceeding:

http://api.jquery.com/jquery.when/

You'd use it like this:

$.when(getWeatherForCity([pass the parameter here])).done(function(){
    // do stuff here after the method is finished
});

You would also need to use a return for your Ajax function like this:

return $.ajax({
        url: weatherUrl + id,
        async: false,
        success: function (data) {
            console.log(data);
            value = data;
        }
    });

Upvotes: 0

dfsq
dfsq

Reputation: 193261

Problem. You problem is that you never call local getWeatherForCity function. So it never changes the value variable. This should fix it:

self.getWeatherForCity = function (id) {
    getWeatherForCity(id);
    return value;
};

Better approach. Looks like you are aware that using async: false is not the ideal solution. In this case I will suggest you better option.

function Weather() {

    var self = this,
        weatherUrl = 'http://api.openweathermap.org/data/2.5/weather?id=';

    function getWeatherForCity(id) {
        return $.get(weatherUrl + id);
    }

    self.getWeatherForCity = function (id) {
        return getWeatherForCity(id);
    };
}

var weather = new Weather();
weather.getWeatherForCity('2878234').then(function(data) {
    console.log(data);
});

Using asynchronous code makes UI non-freezing during request. And usage of promises makes code cleaner and more comprehensive.

Upvotes: 2

Scimonster
Scimonster

Reputation: 33399

You have two different getWeatherForCity() functions - one is a method, and one is a private function (inside the closure). You never call the private function, that actually does the work.

function Weather() {
    var self = this,
        weatherUrl = 'http://api.openweathermap.org/data/2.5/weather?id=',
        value = null;

    function getWeatherForCity(id) {
        $.ajax({
            url: weatherUrl + id,
            async: false,
            success: function (data) {
                console.log(data);
                value = data;
            }
        });
    }

    self.getWeatherForCity = function (id) {
        getWeatherForCity(id); // here
        var cast = value;
        console.log(cast);
        return cast;

    };
}

Upvotes: 1

Related Questions