Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

Michael Williams
PLUS
Michael Williams
Courses Plus Student 8,059 Points

Where am I going wrong with the Google Maps API?

I'm trying to create an app that generates a random map location and displays it. So far, the code is for specific coordinates just to make sure I'm retrieving the data correctly.

I feel like I'm all turned around and am not sure where I'm going wrong, as the AJAX course doesn't translate 100% to what I'm trying to do. Can anyone help me figure out what I'm doing wrong?

A few other things to note:

  1. I'm using VS Code and running it using the http-server package.
  2. My console.log statement isn't logging.
  3. My CSS isn't loading, either. (it does when I run everything through a Treehouse workspace, though) This leads me to believe that things aren't connected properly.
$(document).ready(function () {
    $('button').click(function () {

        console.log("You have click the button.");
        var gmapAPI = "https://maps.googleapis.com/maps/api/js?key=OMMITTED_FOR_PRIVACY&callback=initMap?jsoncallback=?";
        var gmapOpts = {
            center: {lat: -34.397, lng: 150.644},
            zoom: 8
        };
        function gmapCallback(data) {
            var map;
            function initMap() {
              map = new google.maps.Map(document.getElementById('map'), {
                gmapOpts
              });
            }
        }
        $.getJSON(gmapAPI, gmapOpts, gmapCallback);
    });
}); // end ready
<!DOCTYPE html>
<html> 
    <head>
        <meta charset="utf-8">
        <title>Map App</title>
        <link href='http://fonts.googleapis.com/css?family=Varela+Round' rel='stylesheet' type='text/css'>
        <link rel="stylesheet" href="css/style.css">
        <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
        <script src="js/app.js"></script>

    </head>
    <body>

        <div class="grid-container centered">
            <div class="grid-100">
              <div class="contained">
                <div class="grid-100">
                  <div class="heading">
                    <h1>Random Map Generator</h1>
                    <p>Click the button to generate a random map location.</p>
                  </div>
                  <ul class="filter-select" style="list-style: none;">
                    <li><button>Create Map</button></li>
                  </ul>
                </div>
    </body>
</html>

3 Answers

Brendan Whiting
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Brendan Whiting
Front End Web Development Techdegree Graduate 84,736 Points

I assume you're following along with the tutorial in the Google Maps docs. If not, it's a great place to start. A few things I noticed:

  • you should include a <script> tag that loads the google maps api code, similar to how you have a script tag to fetch all the jQuery code onto your website. In the tutorial example, it's at the bottom of the <body> element to make sure everything else has loaded.
<script src="https://maps.googleapis.com/maps/api/js?key=OMMITTED_FOR_PRIVACY&callback=initMap"
        async defer></script>

After it's downloaded, all the google maps code will be inside this variable called google in the same way that all the jQuery code ends up in a variable called $.

  • at the end of that url it says callback=initMap. This means after it finishes fetching all the google maps code onto your website, you're telling it to immediately call some function. In this case it's called initMap. But that function has to be in the global scope for it to be able to find it, you can't have it nested inside of things where it's out of scope.
  • you need to have a DOM element on the page where you're going to mount your map. In the tutorial, they have this in the HTML: <div id="map"></div> and then that corresponds to this part of the JavaScript where it's grabbing that DOM element and using the google maps code that was downloaded to put a map there:
map = new google.maps.Map(document.getElementById('map'), { // grabs the #map DOM element
    center: {lat: -34.397, lng: 150.644},
    zoom: 8
});
  • I'm not sure why the css isn't loading properly. Is it possible you've put the file in a different location in the workspace than on your local machine? Is it inside the css/ directory? But this is critical, because you need to give the #map some explicit height as they have, otherwise it won't be visible at all:
#map {
    height: 100%;
}

In this case, they're saying make the map the full height of the page. But you could also confine your map to some smaller box.

It might be a better strategy to take the tutorial code, get it working on your machine with your API key, and then gradually refactor and change things to make it do what you want.

FYI there's also a free Google Maps course on Udacity partnering with Google.

Michael Williams
Michael Williams
Courses Plus Student 8,059 Points

One more thing to add is that I copy/paste the code from the Google tutorial, and it works. However, if I remove the optional HTML from the style tag (I'm just tinkering at this point to figure out what's the minimum I need in my HTML), it doesn't work. And I don't get any errors. So I'm not sure how to diagnose that. This is the section I removed.

      /* Optional: Makes the sample page fill the window. */
      html, body {
        height: 100%;
        margin: 0;
        padding: 0;
      }
Brendan Whiting
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Brendan Whiting
Front End Web Development Techdegree Graduate 84,736 Points

HTML elements normally get their height from their content, we don't normally have to give them a height in CSS. But for a google map, we do. I'm not sure why, maybe something to do with the way it puts the map in an iframe inside the element. At any rate, you need to give your map an explicit height in CSS or it won't be visible. In the tutorial code, they gave the map height: 100%;, which means taking up 100% of it's parent. But if the parent's height was 0, that's 100% of nothing, so they had to put 100% on the body and html elements as well.

You could also just give your map a pixel value for height. You could have kind of a card-sized map:

#map {
    height: 300px;
    width: 300px;
    border-radius: 10px;
}
Michael Williams
PLUS
Michael Williams
Courses Plus Student 8,059 Points

This is helpful. I found out why some of my code was falling apart, I accidentally deleted my "map" class on the div. Once I put that back in, console.log worked and so did my styling.

But my bigger question, Brendan Whiting, is how can I use my app.js file to get the map and then place it into the DOM, as opposed to doing it within the HTML? Once I fixed my div tag, I got this error in the console, which I don't understand:

jquery-3.3.1.min.js:2 
GET https://maps.googleapis.com/maps/api/js?key=AIzaSyBfH8O1eP7bycQIA_XPOgbLoYJ6W3hIwPk&callback=initMap?jsoncallback=jQuery331030359532877067164_1549250855692&center%5Blat%5D=-34.397&center%5Blng%5D=150.644&zoom=8&_=1549250855693 
net::ERR_ABORTED 400
send @ jquery-3.3.1.min.js:2
ajax @ jquery-3.3.1.min.js:2
w.(anonymous function) @ jquery-3.3.1.min.js:2
getJSON @ jquery-3.3.1.min.js:2
(anonymous) @ app.js:19
dispatch @ jquery-3.3.1.min.js:2
y.handle @ jquery-3.3.1.min.js:2
Brendan Whiting
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Brendan Whiting
Front End Web Development Techdegree Graduate 84,736 Points

It seems like you can also do this:

$.getScript("https://maps.googleapis.com/maps/api/js?key=OMMITTED_FOR_PRIVACY&callback=initMap");

function initMap() {
    map = new google.maps.Map(document.getElementById('map'), {
        center: {lat: -34.397, lng: 150.644},
        zoom: 8
    });
}

But why? In this version, a script loads another script. Your user will have to wait longer to see everything rendered. First, your page will parse the HTML, where it says to download and parse app.js, and then app.js will tell it that it needs to fetch the google maps code. But you could have told the browser sooner when it was parsing the HTML that it needs the google maps script as well, and the browser would fire off requests concurrently for all the scripts.

If you want to only display the map to the user when they click the button, that's fine. Or change the location on the map when they click the button. But you don't need to wait to download the script.

Michael Williams
PLUS
Michael Williams
Courses Plus Student 8,059 Points

The reason is I want practice using a javascript and jquery to use APIs. So it's less of a practical thing and more of trying to understand APIs forwards and backwards.

I think I have had a misunderstanding of APIs, though. I thought they always had to be accessed via a GET request, hence the reason I was trying to map my code to what Dave was doing in the AJAX course. Why don't you have to send a GET request with this API?

Brendan Whiting
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Brendan Whiting
Front End Web Development Techdegree Graduate 84,736 Points

Normally with APIs we fetch some JSON from some url. But in this case, what we’re fetching from that URL is JavaScript code. It’s like jQuery, a library of someone else’s code to use and run in your app.