-1

I am currently loading a json file and then parsing it. The entries in the json file is stored as "places", which I defined as a global variable, but the browser still says it is undefined.

var request;
var places;
var map;
var myLatLng = {lat: 34, lng: 38};

// load database and parse into entries
if (window.XMLHttpRequest) {
    request = new XMLHttpRequest();
} else {
    request = new ActiveXObject("Microsoft.XMLHTTP");
}
request.open('GET', 'places.json');
request.onreadystatechange = function() {
    if ((request.readyState ===4) && (request.status===200)) {
        places = JSON.parse(request.responseText);
    }
}
request.send();

function initMap() {
    var mapOptions = {
        zoom: 6,
        center: myLatLng,
        mapTypeControl: true,
        mapTypeControlOptions: {
            style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR,
            position: google.maps.ControlPosition.TOP_RIGHT
        },
        mapTypeId: google.maps.MapTypeId.HYBRID
    };
    // initialize the map
    var map = new google.maps.Map(document.getElementById('map'), mapOptions);

    for (var i = 0; i < places.length; i++) {
        // the place
        var place = places[i];
        // place co-ordinates
        var latlng = new google.maps.LatLng(place.latitude, place.longitude);
        var marker = new google.maps.Marker({
            position: latlng,
            map: map, 
            title: place.city
        });
    }
}
Victor
  • 21
  • 6
  • I think you've forgotten to add your error log... – user4232 Nov 14 '15 at 07:05
  • 2
    It likely means that `initMap()` is being invoked before the request to `places.json` actually completes and `places` is assigned. Can you also share how `initMap` is being used? Related: [Why is my variable unaltered after I modify it inside of a function?](https://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron) – Jonathan Lonowski Nov 14 '15 at 07:06
  • You forgot to call `initMap` in your `onreadystatechange` function. – Shashank Nov 14 '15 at 07:08
  • @JonathanLonowski, thanks for your help, I actually called the function in an html file. – Victor Nov 14 '15 at 07:30
  • @Shashank, thanks for your help, I just fixed it! – Victor Nov 14 '15 at 07:33

1 Answers1

0

The comments provided by Jonathan Lonowski and Shashank are the most likely causes of the problem you are facing. You need to make sure that you are calling initMap after the AJAX call completes. So you can modify the onreadystatechanged method to something like below:

request.onreadystatechange = function() {
    if ((request.readyState ===4) && (request.status===200)) {
        places = JSON.parse(request.responseText);
        initMap();
    }

However I would want to also clear the concept of undefined in Javascript parlance.

In Javascript when a variable is declared (but no value is assigned to it) it is set to a value of undefined. Note that undefined is not the same as null which is more of an assignment value.

This answer will make clear the confusion between undefined and null. You will then be able to understand why the browser shows the variable places as undefined.

Edit based on comment from OP In case you are calling the method from your HTML file, there is still a way to make the page behave correctly but with some negligible latency.

Refer to an alternate solution that I propose below

var request;
var places;
var map;
var myLatLng = {lat: 34, lng: 38};

// load database and parse into entries
if (window.XMLHttpRequest) {
    request = new XMLHttpRequest();
} else {
    request = new ActiveXObject("Microsoft.XMLHTTP");
}
request.open('GET', 'places.json');
request.onreadystatechange = function() {
    if ((request.readyState ===4) && (request.status===200)) {
        places = JSON.parse(request.responseText);
        //now that the places array has been initialized you can call
        //placeMarkers() to place markers on the map.
        placeMarkers();
    }
}
request.send();

//initMap can be safely invoked within the HTML page using window.onload.
//this only initializes the map instance and sets it to a valid reference.
//there are *no* place markers added yet
function initMap() {
    var mapOptions = {
        zoom: 6,
        center: myLatLng,
        mapTypeControl: true,
        mapTypeControlOptions: {
            style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR,
            position: google.maps.ControlPosition.TOP_RIGHT
        },
        mapTypeId: google.maps.MapTypeId.HYBRID
    };
    // initialize the map. Here map should be the global variable and not a new declaration
    map = new google.maps.Map(document.getElementById('map'), mapOptions);
}

function placeMarkers(){

    for (var i = 0; i < places.length; i++) {
        // the place
        var place = places[i];
        // place co-ordinates
        var latlng = new google.maps.LatLng(place.latitude, place.longitude);
        var marker = new google.maps.Marker({
            position: latlng,
            map: map, 
            title: place.city
        });
    }
}
Community
  • 1
  • 1
Prahalad Deshpande
  • 4,709
  • 1
  • 20
  • 22