Uncaught ReferenceError: google is not defined when trying to use Google Places API without a map

google-places, google-places-api, javascript

Solution

From my reading, `async` and `defer` aren't meant to be used at the same time.

While your `<script>` that loads the API from google is deferred, your `<script>` with your code is not deferred. (If you remove `async` and `defer` your code works, but is theoretically slower.)

If you defer your code execution until the document is loaded (and the google api instantiated), then your code should work.

i.e., as sideroxylon alluded to,

<script>
    $(document).ready(function() {
        var service = new google.maps.places.PlacesService(document.getElementById('list'));
        ...
    })
</script>

or

<script>
    document.addEventListener('DOMContentLoaded', function() {
        var service = new google.maps.places.PlacesService(document.getElementById('list'));
        ...
    })
</script>

...I can not get this to work with `async`, but I can with `defer`. `async` can be run at any time, even after `DOMContentLoaded`. According to this, `defer` does preserve order.

Here's a good resource for execution order: https://www.kirupa.com/html5/running_your_code_at_the_right_time.htm

It shows that `defer` happens just before the `DOMContentLoaded` Event and `async` scripts can execute at any time, although before the final `load` Event.

As to why their example works, note that they add `&callback=initMap` to the API URL, which presumably asks their code to call `initMap()` after their code is initialized. That way you can chain your code (your `initMap()` function) to their asynchronous load. e.g.,

<script>
    // define your callback before you invoke the API.
    function my_code() {
        var service = new google.maps.places.PlacesService(document.getElementById('list'));
        ....
    }
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=APIKEY&libraries=places&callback=my_code" defer async ></script>

Problem

I know this is a really common error, but I read all the other "Uncaught ReferenceError: google is not defined" questions and none of them helped me fix it. I am using the Google Places API but my application does not use a map so I referred to this question to figure that out. Many of the answers talked about loading the api script asyncronously before everything else, and the order of the scripts matters, but I don't think that's my issue. I followed the example in the Places API Documentation so I don't know what I am doing wrong. Here is my code: ``` <!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <meta name="viewport" content="initial-scale=1.0, user-scalable=no"> </head> <body> <h1>Places Near Chicago</h1> <div id="list"></div> <script src="https://maps.googleapis.com/maps/api/js?key=API_KEY&libraries=places" async defer></script> <script> var service = new google.maps.places.PlacesService(document.getElementById('list')); var request = { location: new google.maps.LatLng(41.8781136, -87.6297982), radius: 5 }; service.search(request, callback); function callback(results, status){ if(status == google.maps.places.PlacesServiceStatus.OK){ console.log(status); for (var i = 0; i < results.length; i++) { console.log(results[i].name, results[i].types); } } }; </script> </body> </html> ``` The issue is specifically with the line ``` var service = new google.maps.places.PlacesService(document.getElementById('list')); ``` Thanks! EDIT: I updated my code as per Jeff's suggestion and still get the same error.

Original source

Related problems