3

I recently updated the version of PhoneGap/Cordova I was using to the most recent. There is a page in my app that keeps throwing the following error every time it loads.

Uncaught Reference Error: google is not defined

I tried to use a sample webpage directly from the google developer's site to try and narrow down my options, and still got the same error when trying to load that page on my phone. (found here: https://developers.google.com/maps/documentation/javascript/examples/map-simple). I should note, when running this webpage from google as an .HTML file in Chrome on my desktop it worked fine.

I have also tried to use the solution found here: Google Maps API throws "Uncaught ReferenceError: google is not defined" only when using AJAX

however the initialize method was never even called, which leads me to believe it's a problem with my script tag that I'm still missing.

As far as I can tell, I am using proper script calls in my HTML:

<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?<KEY>&sensor=false"></script>

and the javascript code that is crashing is as follows:

origins[0] = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);

The full code is here:

<!DOCTYPE HTML>
<html>
<head>
<title>MASH Locations</title>
<meta name="viewport"
    content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" />
<link rel="stylesheet" type="text/css" href="styles/layout.css" />
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript"
    src="http://maps.googleapis.com/maps/api/js?key=(myAppKey)&sensor=false"></script>
<script type="text/javascript" charset="utf-8" src="Util.js"></script>
<script type="text/javascript" charset="utf-8" src="QuickSort.js"></script>
<script type="text/javascript" charset="utf-8" src="Location.js"></script>
<script type="text/javascript">
    var origins, destinations;
    var BORDER_ROW = '<tr><td colspan="3" class="location-result-border">&nbsp;</td></tr>';
    var RESULT_FORMAT = '<tr><td id="result_{7}" class="location-result-row" onclick="onLocationResultClick(\'{0}\', \'{1}\', \'{2}\', \'{3}\', \'{4}\', \'http://cloud.intelligentbits.net/mash/images/{5}\', \'{6}\')">'
        + '<table class="{8}">'
        + '<tr><td class="location-result-distance" rowspan="3"><div>{9}</div>miles</td>'
        + '<td class="location-result-logo" rowspan="3"><img src="http://sqldb.intelligentbits.net/mash/images/{5}" alt="{0}" /></td>'
        + '<td class="location-result-name">{0}</td></tr>'
        + '<tr><td class="location-result-address">{10}</td></tr>'
        + '<tr><td class="location-result-city">{11}</td></tr></table></td></tr>';

    function onLoad()
    {
        // Wait for PhoneGap to load
        document.addEventListener("deviceready", onDeviceReady, false);
    }

    // PhoneGap is ready
    function onDeviceReady()
    {
        navigator.geolocation.getCurrentPosition(onPositionFound, onPositionError);
    }

    function onPositionFound(position)
    {   
        // get the current location
        origins = new Array();
        origins[0] = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);

        document.getElementById('finding').innerText = 'Finding our locations...';
        readFile('http://sqldb.intelligentbits.net/mash/locations.txt', onLocationsFound);
    }

    // onPositionError Callback receives a PositionError object
    function onPositionError(error)
    {
        alert('code: '    + error.code    + '\n' +
              'message: ' + error.message + '\n');
    }

    function onLocationsFound(text)
    {
        if (text == null || text.length == 0)
        {
            document.getElementById('finding').innerText = 'An error occurred.';
            return;
        }

        // split the text into lines (one line per location)
        var lines = text.split(/\r?\n/g);
        if (lines.length == 0)
        {
            document.getElementById('finding').innerText = 'An error occurred.';
            return;
        }

        // destinations
        destinations = new Array();
        var locIdx = 0;

        // iterate over lines/locations
        for (var i = 0; i < lines.length; ++i)
        {
            // split into fields
            var loc = new Location();
            var fields = lines[i].split(';');

            for (var j = 0; j < fields.length; ++j)
            {
                // split fields into name and value
                var tokens = fields[j].split('=');
                if (tokens.length != 2) continue;

                switch (tokens[0].toUpperCase())
                {
                    case 'NAME':
                        loc.Name = tokens[1];
                        break;
                    case 'ADDRESS':
                        loc.StreetAddress = tokens[1];
                        break;
                    case 'CITY':
                        loc.City = tokens[1];
                        break;
                    case 'STATE':
                        loc.Region = tokens[1];
                        break;
                    case 'POSTAL':
                        loc.PostalCode = tokens[1];
                        break;
                    case 'PHONE':
                        loc.Phone = tokens[1];
                        break;
                    case 'HOURS':
                        loc.Hours = tokens[1];
                        break;
                    case 'LOGO':
                        loc.LogoFileName = tokens[1];
                        break;
                    case 'EMAIL':
                        loc.Email = tokens[1];
                        break;
                }
            }

            // save the destination
            destinations[locIdx++] = loc;
        }

        if (destinations.length == 0)
            document.getElementById('finding').innerText = 'An error occurred.';
        else
            calculateDistances(origins, destinations);
    }

    function calculateDistances(orig, dest) {
        // the passed-in destinations are arrays of Location objects; Google Maps wants strings
        var destStrings = new Array();
        for (var i = 0; i < dest.length; ++i)
            destStrings[i] = dest[i].ToAddressString();

        var service = new google.maps.DistanceMatrixService();
        service.getDistanceMatrix(
          {
            origins: orig,
            destinations: destStrings,
            travelMode: google.maps.TravelMode.DRIVING,
            unitSystem: google.maps.UnitSystem.IMPERIAL,
            avoidHighways: false,
            avoidTolls: false
          }, onDistancesFound);
    }

    function onDistancesFound(response, status)
    {
        if (status != google.maps.DistanceMatrixStatus.OK)
        {
            alert('Error was: ' + status);
        }
        else
        {
            // get the place we'll store the list
            var p = document.getElementById('finding');
            var table = document.getElementById('location-results');
            var orig = response.originAddresses;
            var dest = response.destinationAddresses;

            p.innerText = 'Tap a location for more options.';

            // iterate over origins
            for (var i = 0; i < orig.length; ++i) {
                var results = response.rows[i].elements;                
                // iterate over destinations
                for (var j = 0; j < results.length; ++j) {
                    // split the location into the amount and units
                    var distance = results[j].distance.text.Trim().split(' ');
                    // update the locations
                    destinations[j].DistanceFromUser = parseFloat(distance[0]);
                    destinations[j].DistanceUnits = distance[1];
                    destinations[j].TimeFromUser = results[j].duration.text;
                }
            }

            // sort the distances
            QuickSort(destinations, 'DistanceFromUser');

            // print the results
            var tablerows = '';
            for (var i = 0; i < destinations.length; ++i) {
                var loc = destinations[i];
                tablerows += RESULT_FORMAT.Format(loc.Name, loc.Phone, loc.ToAddressString(), loc.ToTwoLineAddressString(),
                    loc.Hours, loc.LogoFileName, loc.Email, i, 'location-result-' + ((i + 1) % 2 == 0 ? 'even' : 'odd'),
                    loc.DistanceFromUser, loc.StreetAddress, loc.City);
            }


            tablerows += '<tr><td><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/></td></tr>';

            // append the rows
            table.innerHTML += tablerows;
        }
    }

    function onLocationResultClick(name, phone, address, displayAddress, hours, imageUrl, email)
    {
        // save the name and address to local storage for the directions
        window.localStorage.setItem('location-position', address);
        window.localStorage.setItem('location-address', displayAddress);
        window.localStorage.setItem('location-title', name);
        window.localStorage.setItem('location-hours', hours);
        window.localStorage.setItem('location-phone', phone);
        window.localStorage.setItem('location-imageUrl', imageUrl);
        window.localStorage.setItem('location-contact', email);

        // call link
        window.location = 'location.html';
    }
</script>
</head>
<body onload="onLoad()">
    <h1>
        <a href="index.html" class="back">
            <div>
                <span></span>
            </div> <span class="text">Back</span>
        </a> Nearest Locations
    </h1>
    <div id="location-results-wrapper">
        <h1 style="position: static; width: 94%;">
            <a href="#" class="back">
                <div>
                    <span></span>
                </div> <span class="text">Back</span>
            </a> #
        </h1>
        <table id="location-results">
            <tr>
                <td id="finding" style="vertical-align: top;">Finding your
                    location...</td>
            <tr>
        </table>
    </div>
</body>
</html>

and the exact error log:

06-27 09:06:00.624: E/Web Console(15020): Uncaught ReferenceError: google is not defined at file:///android_asset/www/locations.html:41

Community
  • 1
  • 1
Alex
  • 1,100
  • 1
  • 9
  • 23
  • When I checked HTML source of the [link](https://developers.google.com/maps/documentation/javascript/examples/map-simple) you provided. I found that, it has `` this script tag. But your ` – Amol Chakane Jun 27 '13 at 05:33
  • I tried using that script tag as well, sadly it still produces the same error. – Alex Jun 27 '13 at 12:29
  • If you can provide all code and error log, it may help us to figure out the issue. – Amol Chakane Jun 27 '13 at 12:54
  • I've added the full code and exact error log now. – Alex Jun 27 '13 at 13:08
  • Had a look at [this?](http://stackoverflow.com/questions/14229695/google-maps-api-throws-uncaught-referenceerror-google-is-not-defined-only-whe) – Amol Chakane Jun 27 '13 at 13:34
  • Yes, I tried that yesterday however the initialize method was never even called from the callbacks, which leads me to believe it has to be something wrong with my script tag that I still can't figure out. I'll add this to the main post so people can see it easier. – Alex Jun 27 '13 at 13:55

4 Answers4

0

Try these

  • Check your internet connection
  • Keep Map API script tag as a first script tag in your code. i.e Before loading any other javascripts load map API.

Hope this helps.

Amol Chakane
  • 1,501
  • 2
  • 21
  • 43
  • Sadly no luck with that, though on your idea that it is running google too late, I did add this script in to try and make it wait for google but I still had no luck: `function LoadGoogle() { if(typeof google != 'undefined' && google && google.load) { // use google.load() here } else { // Retry setTimeout(LoadGoogle, 30); } } LoadGoogle();` What's also weird is that when I use the older version of PhoneGap I originally wrote this on (2.5) the exact code in my original post works. – Alex Jun 27 '13 at 15:50
0

I found my solution. When running the update command for PhoneGap, the cordova.js and config.xml files were not copied over into the my project. I'm not sure if this is intentional (I easily could have missed documentation on this somewhere), but it seemed unintuitive at the time. After manually copying these two files into my project, everything worked.

Alex
  • 1,100
  • 1
  • 9
  • 23
  • 1
    Good you found the solution. Better mark it as answer, it may help someone someday. – Amol Chakane Jun 28 '13 at 05:06
  • It says I still have 7 hours before I am allowed to mark it, but yes I definitely plan on it. Thank you a ton for your help :) – Alex Jun 28 '13 at 12:32
0

When u're using multiple HTML pages. use the google API javascript on the main page(index). the Ajax will not relaod the map when its refreshed.

0

If google map api is not defined then it too can cause the problem. Since i missed out while getting the address from latitude and longitude.