Advise to overcome Javascript hoisting

105 views Asked by At

I suppose that my javascript code suffers from hoisting effects which I would like to sort out.

I'm fetching data via SOAP that I want to visualize on a heatmap, these data are stored in the global variable heatMapData inside the "ajax" code block and then they should be assigned to google.maps.visualization.HeatmapLayer constructor. Unfortunately when this constructor is called the variable heatMapData is empty, although it has been correctly initialized with the instruction heatMapData.push({location: new google ...), I checked it with firebug. . It might happen because this variable is hoisted. How can I keep the values in heatMapData after the return from the ajax code? Thank you in advance.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
    <title>Energy Heatmap </title>
    <style>
      html { height: 100% }
      body { height: 100%; margin: 0; padding: 0 }
      #map-canvas { height: 80% }
      h1 { position:absolute; }
    </style>
    <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?libraries=visualization&sensor=true?key=AIzaSyCzoFE1ddY9Ofv0jjOvA3yYdgzV4JvCNl4"></script>
   <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
 <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
  </head>
  <body>
    <h1>Energy Heatmap </h1>
    <div id="map-canvas"></div>
    
    <script>
var heatMapData = new Array();
function loadHeatMapData()
{
    $.ajax
    ({
        type: "GET",
        url: "http://localhost:8080/EnergyManagement-portlet/api/secure/jsonws/sample/get-samples-time-by-name?energyName=EnAssTCU",
        dataType: "jsonp",
        crossDomain: true,
        cache: false,
        success: function(jsonData)
        {

            for (var i = 0; i < jsonData.length; i++) 
            {
                var decodedData = JSON.parse(jsonData[i]);
                var lng = decodedData["_longitude"]; 
                var lat = decodedData["_latitude"];
                var energyIntensity = decodedData["_value"];
                //Here I add values to heatMapData
                heatMapData.push({location: new google.maps.LatLng(lat, lng), weight: energyIntensity});
            }
        }
    })
}

// map center
var myLatlng = new google.maps.LatLng(40.8333333, 14.25);
// map options,
var myOptions = {
    zoom: 5,
    center: myLatlng,
    mapTypeId: google.maps.MapTypeId.TERRAIN
};
// standard map
map = new google.maps.Map(document.getElementById("map-canvas"), myOptions);
loadHeatMapData();
var heatMap = new google.maps.visualization.HeatmapLayer({
    data: heatMapData //heatMapData is empty
});

heatMap.setMap(map);

var vehiclePath = [
    new google.maps.LatLng(40.85235, 14.26813),
    new google.maps.LatLng(40.85236, 14.26822),
    new google.maps.LatLng(40.85236, 14.26822),
    new google.maps.LatLng(40.85236, 14.26816),                                    
    new google.maps.LatLng(40.85258, 14.26811),
    new google.maps.LatLng(40.85364, 14.26793),
    new google.maps.LatLng(40.85414, 14.26778),
    new google.maps.LatLng(40.8554, 14.2676),
    new google.maps.LatLng(40.8579, 14.27286),
    new google.maps.LatLng(40.85821, 14.27291),
    new google.maps.LatLng(40.8584, 14.27302),
    new google.maps.LatLng(40.85859, 14.27325),
    new google.maps.LatLng(40.8587, 14.27421),
    new google.maps.LatLng(40.85865, 14.27433),
    new google.maps.LatLng(40.85866, 14.27446),
    new google.maps.LatLng(40.86656, 14.291),
    new google.maps.LatLng(40.86653, 14.29102)

];

var path = new google.maps.Polyline({
    path: vehiclePath,
    geodesic: true,
    strokeColor: '#FF0000',
    strokeOpacity: 1.0,
    strokeWeight: 2
});

path.setMap(map);
      
       
</script>
<p id="demo"></p>
  </body>
</html>

1

There are 1 answers

0
T.J. Crowder On

The issue you're having has nothing to do with hoisting, and everything to do with timing.

The $.ajax call starts the process of loading the data from the server, but your code continues to run while that request is outstanding. That's why ajax has a callback — so you can act on the data when it comes back, since it won't be available right away.

So you can't use your heatMapData until after the ajax success callback completes. Move the code that you want using it into a function you call from that callback.