views:

66

answers:

3

I need to get the JSON object data out of the callback function so that I can process it later in page, not within the callback as I am now. It must be obvious to everyone else as I can't see anything written about it. Can anyone tell me how to do it?

Here is my code:

<script type="text/javascript" src="/site_media/js/jstree/_lib/jquery.js"></script>  
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"&gt;&lt;/script&gt;
<script type="text/javascript">
    function initialize() {
        var myLatlng = new google.maps.LatLng(-25.363882,131.044922);
        var myOptions = {
            zoom: 4,
            center: myLatlng,
            mapTypeId: google.maps.MapTypeId.ROADMAP,
        }
        map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
        return map;
    }

    function add_marker(map, lat, long) {
        var marker_image='/site_media/images/map_marker.png';
        var myLatlng = new google.maps.LatLng(lat,long);
        title='title';
        var marker = new google.maps.Marker({
            position: myLatlng, 
            map: map, 
            title:title,
            icon:marker_image
        }); 
        //map.panTo(myLatlng);
    }

    //window.onload=initialize();
    setTimeout('map=initialize();',2000);

    $.getJSON("/ajax/get", function(data) {
        $.each(data, function(i,val) {
            latitude = val.fields.latitude;
            longitude = val.fields.longitude;
             add_marker(map, latitude, longitude);
        });
    });
</script>
<div id="map_canvas" style="width: 500px; height: 300px"></div>
+1  A: 

You need to execute $.getJSON() (and other initialization stuff which depends on the presence of certain HTML elements in the document) during window.onload, or more the jQuery way, during $(document).ready(). Otherwise it is indeed been executed too early, namely immediately when the webbrowser retrieves the JS code, far before the HTML document is finished loading.

$(document).ready(function() {
    $.getJSON("/entries/get_race_entries/1/demo/1", function(data) {
        // ...
    });
});
BalusC
I think I just read that you should never wrap asyncronous code in syncronous code. I think that is what I am trying to do so perhaps I should look for another pattern to solve the problem. Lets say I have drawn 1000 markers, i don't want to redraw them on each Ajax call. Perhaps if I ammend the ajax URL each time to send the last marker received so I don't get it again then I will just draw the next lot coming through. The question is then, how do I store the last marker added. I still need to get it out of the callback for the next time I make the ajax call. Humm, help!
Rich
The problem with this pattern is that it is all about ajax and not enough about the page and it's contents. I want to create the map then add markers as they become available, i.e., timed ajax calls, not timed map creates. As an aside, the reason I have the map in the timer instead of body onload or windowonload is that I haven't worked out how to get the map object out of window.onload so that I can then add markers to it. I usually like to make things difficult for myself and you can see I have done it this time as well!
Rich
@Rich - You haven't explained how all these timed updates will work. How does the AJAX call change from call to call? etc.... and more importantly, why do you need periodic server calls instead of just one call to get all the markers.
Peter Ajtai
OK, it's simply because at time A we have x number of markers and at time B we have y markers. They may appear at 100 per hour perhaps. So I will pole the server the first time with something like /data/get/0 and the next time /data/get/10234 where 10234 is the last marker received. That way I don't receive the whole lot again. So I want to draw a blank map, setinterval the ajax calls and draw marker each time i call depending on what results I get back. How do you get a new line when adding comments!! Thanks Peter, Rich
Rich
+1  A: 

It's hard to help without a clearer idea of what you're trying to achieve, but it sounds like you are trying to manage a large amount of markers.

There are actually already existing solutions for this. Take a look at Handling Large Amounts of Markers in Google Maps.

The Google Marker Manager is in the GMaps Utility Library. You might find some of the descriptions of examples useful.

The marker manager is introduced here, and there are 2 examples on that page you can look at: a weather map, and Google offices.

For more info you can look at the documentation for the Open Source Marker Manager.

Of course, you first should get a simple map with just one set of markers displaying up and running. I think Balus' answer will help you with that.

Peter Ajtai
Thanks for the tips on large numbers of markers, that will really help
Rich
+1  A: 

Rich, its actually much simpler than you think (at least it seems that way). I am assuming your markers have an id or something. You may need to adjust this to work just how you want:

var lastMarkerId; // We'll store the id here, starts as undefined

function refresh_markers () {
  $.getJSON("/ajax/get", { marker_id: lastMarkerId }, function(data) {
    $.each(data, function(i,val) {
        latitude = val.fields.latitude;
        longitude = val.fields.longitude;
        add_marker(map, latitude, longitude);
    });
    if (data.length) {
       // grab the last item and store its ID
       lastMarkerId = data.pop().id;
    }
  });
}

Then on your server, do something like: "If marker_id has a value, find every marker after that id, otherwise, return them all".

Remember! Each marker needs an id for my code to work:

[{id:1, fields: {latitude: "..", longitude: ".." }}]
Doug Neiner
I get it now, it's all about global variables. I was trying to pass the data around but we just need to fudge it with globals. No worries as we say here in Oz! Thanks for your help guys, it all become clear whilst realising I was trying to mix asyn with sync. This forum is amazing for people like me who have no colleagues!
Rich
@Rich - Don't forget to vote up answers you found useful and accept the answer (if any) that solved your problem.
Peter Ajtai
OK, will do thanks
Rich
This answer solved my problem, just use global variables, easy! Thanks Doug
Rich
You are welcome Rich! Glad it was what you needed!
Doug Neiner