1

I am trying to load a google map with a number of markers. This code is called in a onload:

    <body onload="initialize()">

Here is the javascript in question, within a <script> section :

    var map; 
    var address = String("Chicago, Illinois")+" USA"; 
    var lat = null; 
    var long = null;
    var country = null; 
    var geocoder = new google.maps.Geocoder();
    var oms = new OverlappingMarkerSpiderfier(map,{markersWontMove: true, markersWontHide: true, keepSpiderfied: true});
    var iw = new google.maps.InfoWindow();
    oms.addListener('click',function(marker) {
        iw.setContent(marker.desc);
        iw.open(map,marker);
    });

    var contentString = '+String("Soldier Field")+"<br>"+latlng+'
    var infowindow =  new google.maps.InfoWindow();
    var marker, i, markerAddress;
    var facilities = "Soldier Field"; 
    var cities = "Chicago";
    var states = "Illinois"; 
    var coords = "41.862338,-87.615855";
    var phones = "312-235-7000"; 
    var url = "www.soldierfield.net"; 
    var briefText = "descriptive text"; 
    var lastUpdated = "2014-05-02"; 
    var overallContactName = "John Smith";
    var overallContactPhone = "312-235-7000"; 
    var overallContactEmail = "john.smith@email.com"; 
    var latlngStr;
    var image = {
        url: 'https://www.google.com/mapfiles/kml/paddle/ylw-stars.png',
        size: new google.maps.Size(40, 40),
    };

    var address_components = null;
    var tmpResult = null;
    var markers = []


    function initialize() { 

        var latlng = new google.maps.LatLng("41.862338", "-87.615855");
        //check if address in the US
        $.ajax({
            url: 'https://maps.googleapis.com/maps/api/geocode/json?latlng='+{{lat}}+','+{{long}}+'&sensor=false',
            async: false,
            dataType: 'json',
            success: function(data) {
                $.each(data.results[0].address_components, function(index,comp) {
                    if (comp.types == 'country,political') {
                        country = comp.short_name;
                        return;
                    }
                });
            }
        });
        if (country == "US") { 
            var mapOptions = {zoom: 8,center: latlng, scrollwheel: false,}; 
            map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);

            var circle = new google.maps.Circle({
                center: latlng,
                radius: {{search_distance}} * 1609.34,
                strokeColor: "#0000FF",
                strokeOpacity: 0.6,
                strokeWeight: 0.5,
                fillColor: "#0000FF",
                fillOpacity: 0.05,
               });          
            circle.setMap(map);
            map.fitBounds(circle.getBounds()); 
            drop(); // drop pins! 
            }
    } // map initialized 

    function geocode(facility,city,state) {
        $.ajax({
                    url: 'https://maps.googleapis.com/maps/api/geocode/json?address='+encodeURIComponent(facility)+"+"+encodeURIComponent(city)+"+"+encodeURIComponent(state)+'&sensor=false',
                    async: false,
                    dataType: 'json',
                    success: function(data) {
                        console.log('https://maps.googleapis.com/maps/api/geocode/json?address='+encodeURIComponent(facility)+"+"+encodeURIComponent(city)+"+"+encodeURIComponent(state)+'&sensor=false')
                        console.log(data.status)
                        lat = data.results[0].geometry.location.lat;
                        lng = data.results[0].geometry.location.lng;
                        address_components = data.results[0].address_components; 

                    }
                })
        return [lat, lng, address_components]; 
    }
    function drop() { 

        for (j = 0; j < facilities.length; j++) {
            setTimeout(function() {
                addMarker(); 
            }, j*200);
        }
    }
    function addMarker() {
        latlngStr = coords[j].split(","); 
        tmpResult = geocode(facilities[j],cities[j],states[j]);
        lat = tmpResult[0]
        lng = tmpResult[1]
        address_components = tmpResult[2]

        // clever solution to parse address_components: http://stackoverflow.com/a/16429122/3058197
        var components = {}; 
        jQuery.each(address_components, function(k,v1) {jQuery.each(v1.types, function(k2, v2){components[v2]=v1.long_name});})

        latlng = new google.maps.LatLng(lat,lng); 
        marker = new google.maps.Marker({
            position: latlng,
            map: map,
            title: facilities[j],
            animation: google.maps.Animation.DROP,
            }));
        oms.addMarker(marker);
        markers.push(marker); 
    }

The error I am seeing in the javascript console is:

ReferenceError: initialize is not defined

Any idea? Thanks

user3058197
  • 1,052
  • 1
  • 9
  • 21
  • 1
    Javascript always will be inside ` – Dhaval Marthak May 02 '14 at 15:28
  • 1
    When I paste your script in the console, it has a syntax error. If you script has a syntax error, the function is basically not defined, because the code is never run. Oh, I guess you are using a server side templating engine - you better replace the variables with actual values for the purpose of this question. – PhistucK May 02 '14 at 15:29
  • All that var identifier={{identifier}} stuff makes no sense – Pablo Lozano May 02 '14 at 15:32
  • Sorry -- the {{ }} stuff is jinja templating that I'm using. The code is after body. Should I put it before? I'm editing the code above to remove the templating. – user3058197 May 02 '14 at 15:36
  • @user3058197 you left some more {{}}, so there are still syntax errors. http://jslint.com/ can help you see the syntax errors (make sure you tick everything in the bottom options section, or else you would get irrelevant errors for this purpose). – PhistucK May 02 '14 at 15:42
  • Among other things, the geocoder is asynchronous, you can't return anything from it. Note that I don't see the error in the title. – geocodezip May 02 '14 at 16:03
  • [jsfiddle showing map](http://jsfiddle.net/E8LDE/) – geocodezip May 02 '14 at 16:22
  • Geocodezip, I don't know if I understand.. because that part of the code works...? – user3058197 May 02 '14 at 19:05

4 Answers4

1

Try adding this to your code:

document.getElementsByTagName('body')[0].onload = initialize;

It's probably out of scope.

Alex W
  • 37,233
  • 13
  • 109
  • 109
  • Thank you for the reply -- can you tell me where to put it? – user3058197 May 02 '14 at 15:34
  • 1
    @user3058197 It shouldn't matter where because the `initialize` function definition will be hoisted. For readability and clarity, I would say at the bottom of your code. – Alex W May 02 '14 at 15:35
  • Is there any reason not to use `document.body` instead of the long method? Or even `window.onload` (or `window.addEventListener('load', initialize, false);` for best practices)? – PhistucK May 02 '14 at 15:38
  • 1
    @PhistucK Generally, `document.body` is perfectly fine and is actually faster, but it will return a `frameset` element if used on frameset documents, so it's not 100% equivalent to body `onload`. Using `window.onload` is also not equivalent and `addEventListener` is not supported by older IE so you would need to also use `attachEvent`. – Alex W May 02 '14 at 15:51
  • For the purpose of this question, I think window.onload is totally equivalent. And obviously, I meant the whole addEventListener/attachEvent charade. – PhistucK May 02 '14 at 15:52
1

The likely issues are:

  1. You have a script error that stops the parsing of your script so everything after the error is undefined. Check your error console for script parsing errors and fix all that you find. Unless you're using some sort of templating engine that replaces these, code like this is not legal javascript: var cities = {{cities}};.

  2. Your function initialize() is not defined in the global scope (which it must be for the initalization from the onload attribute). If this was the case, then you need to either assign it differently to onload so you can use a function that isn't in the global scope or move it to the global scope.


FYI, since you appear to be using jQuery already, you can use the built-in capabilities in jQuery rather than wait for onload:

$(document).ready(initialize);

though this will only fix your problem if it's #2 above (and you place this line of code in the same scope as the initialize function), not if the issue is #1 above.


P.S. If you share a running page link, we could probably solve this in minutes rather than just take guesses.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
0

not sure why it is not calling your function, however, I usually use the following method to call the initialise method...

<html>
<head>
...
</head>
<body>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>
<script>
  function initialise(){
     ...
  }
  google.maps.event.addDomListener(window, 'load', initialise); 
</script>
...
Aurovrata
  • 2,000
  • 27
  • 45
  • It will not work. Please check out the name of the function which is being called (It seems typo error. Please edit it Or please delete this answer) – ArunRaj May 03 '14 at 02:42
  • 1
    quite right, I made a typo on the listener call...thanks for pointing out! Corrected in code... – Aurovrata May 09 '14 at 17:39
0

@user3058197: There are plenty of typo mistakes and misconceptions are in your code.

Please check out the following

Line 14: var contentString --- Missing semicolon.
Line 31: size: , --- Extra comma at the last line.
Line 36: var markers  --- Missing semicolon.
Line 44: Dont pass null values better use the following

var latLng = new google.maps.LatLng("41.862338", "-87.615855");
//check if address in the US (The below is better than your previous code) 
$.ajax({
url: 'https://maps.googleapis.com/maps/api/geocode/json?latlng='+ latLng
+'&sensor=false'});
Line 57: var mapOptions = {,}; --- Extra comma at the end of the json object.

I just pointed out something. Please use firebug to debug your javascript code. Please go through this documentation

ArunRaj
  • 1,780
  • 2
  • 26
  • 48