views:

143

answers:

2

Hi. Code not working because of async query and variable scope problem. I can't understand how to solve this. Change to $.ajax method with async:false - not an option. I know about closures, but how I can implement it here - don't know. I've seen all topics here about closures in js and jQuery async problems - but still nothing. Help, please. Here is the code:

var map = null;
var marker;
var cluster = null;

function refreshMap() 
{
    var markers = [];  
    var markerImage = new google.maps.MarkerImage('/images/image-1_32_t.png', new google.maps.Size(32, 32));

    $.get('/get_users.php',{},function(data){
        if(data.status == 'error')
            return false;

        var users = data.users; // here users.length = 1 - this is ok;  
        for(var i in users)
        {
            //here I have every values from users - ok
            var latLng = new google.maps.LatLng(users[i].lat, users[i].lng);
            var mark = new google.maps.Marker({
                position: latLng,
                icon: markerImage
         });

             markers.push(mark);
             alert(markers.length); // length 1
        }

    },'json');

    alert(markers.length); // length 0  
    //if I have alert() above - I get result

    cluster = new MarkerClusterer(map, markers, 
    {
        maxZoom: null,
        gridSize: null
    });
}

Thanks.

A: 

All your code that has to deal with markers has to be in your callback function. This line of code:

alert(markers.length); // length 0  

is executed before the Ajax call returns (i.e. before the callback is executed).


That means your code should look more like this:

$.get('/get_users.php',{},function(data){
    if(data.status == 'error')
        return false;

    var users = data.users; // here users.length = 1 - this is ok;  
    for(var i in users)
    {
        //here I have every values from users - ok
        var latLng = new google.maps.LatLng(users[i].lat, users[i].lng);
        var mark = new google.maps.Marker({
            position: latLng,
            icon: markerImage
         });

         markers.push(mark);
         alert(markers.length); // length 1

         cluster = new MarkerClusterer(map, markers, 
                   {
                           maxZoom: null,
                           gridSize: null
                   });

         // more with cluster here
     }
},'json');

If you set or change variables in an Ajax callback, don't rely on their values outside of the callback.

Felix Kling
Already done.thank you )
+1  A: 

Just move this code:

cluster = new MarkerClusterer(map, markers, 
{
    maxZoom: null,
    gridSize: null
});

Into the callback function (where your first alert is)

The problem is that with an async request the code will continue to execute even though the request has not completed. So your markers variable isn't set properly until your anonymous callback function is executed.

joshperry
Yes, you're right. Works fine. Thank you.Shame on me.
Look, but what if I need to push some data in var markers from $.get(..) scope ?
Then you would need to move that variable to a higher scope than the one you need to reference it from.
joshperry