views:

49

answers:

2

How do I make this function return the entire array when it's done pushing all markers?

function XTW_getLocations(data, div_id, map) {
    var markers = [];
    var marker;
    var latLngBounds = new google.maps.LatLngBounds();
    $(div_id).empty();
    $.getJSON('GetLocations', "country=" + data.id,
        function(data){
            $.each(data, function(index, data) {
                latLngBounds.extend(new google.maps.LatLng(data.location.latitude, data.location.longitude));
                $(div_id).append( new Option(data.name, data.id ) );
                marker = createMarker(data, icon, html, map);
                markers.push(marker);
            });
            map.fitBounds(latLngBounds);
        });
    return markers;
}
+2  A: 

You can't return it, since it's asynchronous (it gets populated when the response comes back, way after the function's already returned).

You can however use it for something else, for example: passing it to another function when it's ready/populated, like this:

function XTW_getLocations(data, div_id, map) {
    var markers = [];
    var marker;
    var latLngBounds = new google.maps.LatLngBounds();
    $(div_id).empty();
    $.getJSON('GetLocations', "country=" + data.id,
        function(data){
            $.each(data, function(index, data) {
                latLngBounds.extend(new google.maps.LatLng(data.location.latitude, data.location.longitude));
                $(div_id).append( new Option(data.name, data.id ) );
                marker = createMarker(data, icon, html, map);
                markers.push(marker);
            });
            anotherFunction(markers);
            map.fitBounds(latLngBounds);
        });
}
Nick Craver
So by having it inside getJSON() and after each() anotherFunction() won't be called until each() is done?
M.E
But how to I get it back to the var that called XTW_getLocations in the first place..?
M.E
@M.E - Correct on the first comment, for the second: you don't, you pass the data somewhere else, wherever it's needed once it's available. You can pass a callback function into `XTW_getLocations` or always pass it to the same function inside, but not return in. The only way to do that is to make it synchronous, which locks up the browser.
Nick Craver
... Which is a problem as the array is for storage. I need it to be available on request from the user for a new search..
M.E
@M.E - you can't have it available before the data comes back, and that takes time, I'm not sure how to explain that any better...AJAX isn't instant.
Nick Craver
Have a better solution then? The page is a search. Upon search it gets the result (autocomplete) and fetches all nearby locations in the database, lists it all on the map and saves the Google Map markers in an array. I then need the array to be used if a marker is selected for a new search for nearby locations related to *that* selection.
M.E
@M.E - You can set a global variable to the array once you're done, that's no problem...and your marker click function and whatever else can use it, you just can't *immediately* return it to anything :)
Nick Craver
Well that's not really the issue I'm having (sorry if it was vague), I just need to return the array *when* the markers are placed and ready. The first code I provided returned the array right away which was my issue. Nevermind the *time* it takes, that's not *my* problem. ;)
M.E
@M.E - Why do you need to return it? That's my question, whatever you're using it for later, you can call as the `anotherFunction` above...that's how it's *supposed* to work....
Nick Craver
I need it for repeated use of *this* function, which would clear the array and repopulate it, and also to make it interact with a selection list (selection in list highlights marker and vice versa)
M.E
So data in XTW_getLocations() is, in fact, after the first search, the very same array of markers it creates..
M.E
@M.E - yup since you're looking/creating them in the `$.each()` loop, so when you call the function above, they're populated/ready to go.
Nick Craver
+1  A: 

You don't, the AJAX query (getJSON) is asynchronous meaning that as soon as you issue the call you're out of the normal order of processing, you instead use a callBack, just as you do when calling getJSON:

function XTW_getLocations(data, div_id, map, callBack) {
    var markers = [];
    var marker;
    var latLngBounds = new google.maps.LatLngBounds();
    $(div_id).empty();
    $.getJSON('GetLocations', "country=" + data.id,
        function(data){
            $.each(data, function(index, data) {
                latLngBounds.extend(new google.maps.LatLng(data.location.latitude, data.location.longitude));
                $(div_id).append( new Option(data.name, data.id ) );
                marker = createMarker(data, icon, html, map);
                markers.push(marker);
            });
            map.fitBounds(latLngBounds);
            callBack(markers); //Callback goes here
        });
    //return markers;
}

Now, when calling XTW_getLocations you need to add a callback to your call:

XTW_getLocations({some:'data'},'#map','map.png',function(markers){
    //Handle markers here
})
Kristoffer S Hansen
And I could just return the markers there instead then?
M.E
Unfortunately no... you will never be able to return the markers to anywhere in particular, but you _can_ handle the data in the callback, or instead of an anonymous function use a named function if you want to reuse it.
Kristoffer S Hansen
I tried it out quickly tho and return XTW_getLocations(x,x,x, function(markers){return markers;}) *SEEMS* to work. But this isn't the case then? It's just luck?
M.E
Actually I tried it again but with a JSON that returned 2557 objects (i.e made my laptop vomit) and the callback registers equal amounts so it seems to work out pretty well.
M.E