0

Hey Im currently using the Google API to render a map onto my application; however, I am running into a problem where Im using the Google's Geocoding library but it is running into an uncaught error: google is not defined.

I dont understand this error, because I use it to render the map itself, and the google object is being read and rendering the map fine.

Here is my html scripts:

   <script src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
   <script type="text/javascript" src="js/scripts.js" async></script>
   <script 
      src="https://maps.googleapis.com/maps/api/js?key=APIKEY&callback=initMap" async defer>
    </script>

And here is my javascript file:

function initMap() {
var geocoder = new google.maps.Geocoder(),
fromLatLng = getLatLng(geocoder, "Pasadena, California"),
startLatLng = getLatLng(geocoder,"Los Angeles, California"),
fromLocation = new google.maps.LatLng(fromLatLng),
destLocation = new google.maps.LatLng(startLatLng),
map = new google.maps.Map(document.getElementById('map'), {
  center: {lat: 32.8615616, lng: -117.2188185}, // TODO change to start location
  zoom: 7 // continet level
}),
directionService = new google.maps.DirectionsService(),
directionRender = new google.maps.DirectionsRenderer({
  map: map
}),
markerA = new google.maps.Marker({
  position: fromLocation,
  title: "Point A",
  label: "A",
  map:map
}),
markerB = new google.maps.Marker({
  position: destLocation,
  title: "Point B",
  label:"B",
  map:map
});


console.log(fromLocation)
renderRoute(directionService, directionRender, fromLocation, destLocation);

 } // end of initMap


function getLatLng(geocoder, address) {
 geocoder.geocode({'address': address}, function(results, status) {
if (status === 'OK') {
  if(results[0].geometry.location){
    console.log("Successfully Lat/Lng converted");
    return results[0].geometry.location;
  }
  else{
    console.log("Couldn't properly convert");
  }
  } else {
  console.log('Geocode was not successful for the following reason: ' + status);
  }
  });
  }

I've tried changing around the scripts and a lot of other stackoverflow posts but havent found any luck.

Louys Patrice Bessette
  • 33,375
  • 6
  • 36
  • 64
exAns
  • 103
  • 1
  • 2
  • 10
  • 1
    Why did you put async and defer? – Rax Weber Oct 07 '16 at 04:34
  • just read from multiple resources that it was a good convention to do. – exAns Oct 07 '16 at 04:50
  • Please provide a [mcve] that demonstrates the issue. The posted code will only encounter that error if the getLatLng function is called somewhere before the script has loaded. – geocodezip Oct 07 '16 at 06:09
  • 1
    @geocodezip what part of those guideline am i missing? just read through it and seems i have minimal AND complete code, just enough to show my error. And im not providing a bad reasoning for the error. im sure theres some guidelines to a comment as well so make sure to look at that. As just saying i can encounter the error if the latlng function is called somewhere before the script is loaded – exAns Oct 07 '16 at 14:54
  • Your post doesn't include the HTML/CSS for the map or any indication of how the getLatLng function is being called. I doubt I can reproduce the error without doing something I know would cause it (calling that function before the API has loaded). – geocodezip Oct 07 '16 at 15:20
  • @geocodezip: the only HTML needed for a Google map made with API v3 is `
    ` and the only CSS is `#map {height: 100%;}`... Keep it in mind ;)
    – Louys Patrice Bessette Oct 10 '16 at 20:00
  • That may be true, but it isn't there, nor is any indication of how the getLatLng function is being called. I can guess, but if I find a problem, it isn't necessarily the one the OP is experiencing. – geocodezip Oct 10 '16 at 20:29
  • @geocodezip: `getLatLng` was called on the 2nd and 3rd lines of `initMap` function, in OP question. – Louys Patrice Bessette Oct 10 '16 at 20:31
  • Missed that, and missed the attempt to return a value from getLatLng (among all the console.log statements). That just makes this one of the thousands of duplicates of how do I return a value from an asynchronous service. – geocodezip Oct 10 '16 at 21:03
  • duplicate of [How do I return the response from an asynchronous call?](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – geocodezip Oct 10 '16 at 21:48
  • @geocodezip: maybe you're right about the large coding principle... But specifically on the use of `geocoder` with `map API v3`, the answer you suggest does not answer the call. It's not a duplicate of that answer. – Louys Patrice Bessette Oct 10 '16 at 22:12

1 Answers1

1

Your geocode use wasn't right.
   I have to admit that it was a tricky one!
   I never used that service before... I even had to enable it!!

What I found out is that it has a delay to retreive the info.
Yeah... It's a get request after all...
And you do it twice.

So what I did is to set an interval to check if both 2 Geocode resquests callback had executed before setting the map, since needed to set the markers.

I implemented it in a new function which I called doGeocode().
This is also your map API callback in the script call, instead of initMap.

This function, after getting the 2 geocodes latitude/longitude, finally calls the initMap() to render your desired result.

The only thing I couldn't find out is your renderRoute function... Since not provided in your question. But I think you will be able to handle it.

So... Have a look at the result on my server here.

The full code:

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
    <meta charset="utf-8">
    <title>SO # 39909383</title>
    <link rel="icon" type="image/gif" href="https://www.bessetteweb.com/cube-fallback/images/sept.gif">

    <!-- jQuery -->
    <script src="https://code.jquery.com/jquery-1.12.0.min.js"></script>

    <!-- Google Maps CSS-->
    <link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Open+Sans:300">

    <style>
    html, body {
        height: 100%;
        margin: 0;
        padding: 0;
    }
    #map {
        height: 100%;
        cursor: pointer !important;
    }
    </style>
    </head>
  <body>
  <div id="map"></div>

  <script>
    var map;
    var fromLocation;
    var destLocation;
    var callbackCounter=0;

    function initMap() {

        console.log("Map initialisation");

        map = new google.maps.Map(document.getElementById('map'), {
            center: {lat: 32.8615616, lng: -117.2188185}, // TODO change to start location
            zoom: 7, // continent level
            mapTypeId: google.maps.MapTypeId.SATELLITE      // TERRAIN, HYBRYD, ROADMAP
        });

        var directionService = new google.maps.DirectionsService();
        var directionRender = new google.maps.DirectionsRenderer({
            map: map
        });

        var markerA = new google.maps.Marker({
            position: fromLocation,
            title: "Point A",
            label: "A",
            map:map
        });

        var markerB = new google.maps.Marker({
            position: destLocation,
            title: "Point B",
            label:"B",
            map:map
        });

        // renderRoute == not a function!!
        // Missing in the question...
        // Temporarly commented out.
        //
        //renderRoute(directionService, directionRender, fromLocation, destLocation);

    } // end of initMap

    function getLatLng(geocoder, address) {
        geocoder.geocode({'address': address}, function(results, status) {

            console.log("callbackCounter: "+callbackCounter);

            if (status === 'OK') {
                if(results[0].geometry.location){
                    console.log("Successfully Lat/Lng converted");

                    // Only to see clearly in console.log()
                    var latlong = JSON.stringify(results[0].geometry.location);
                    console.log( latlong );

                    latlong = JSON.parse(latlong);
                    callbackCounter++;

                    // Set from
                    if(callbackCounter==1){
                        fromLocation = latlong;
                    }

                    // Set dest
                    if(callbackCounter==2){
                        destLocation = latlong;
                    }

                    // Function end.
                    return;
                }
                else{
                    console.log("Couldn't properly convert");
                }
            } else {
                console.log('Geocode was not successful for the following reason: ' + status);
            }
        });
    }

    function doGeocode(){
        var geocoder = new google.maps.Geocoder();

        getLatLng(geocoder, "Pasadena, California");
        getLatLng(geocoder,"Los Angeles, California");

        // Wait for from and dest locations found ( Geocoder get delay )
        var waitForCoords = setInterval(function(){
            console.log("--- Interval");

            if(callbackCounter==2){
                clearInterval(waitForCoords);
                console.log("--- Interval cleared");

                // Ready to initialise the map!
                initMap();
            }

        },50);
    }
    </script>
    <script async defer src="https://maps.googleapis.com/maps/api/js?key=[YOUR_API_KEY]&callback=doGeocode"></script>

</body>
</html>
Louys Patrice Bessette
  • 33,375
  • 6
  • 36
  • 64