1

I have a page that uses Google Maps API to display a Map with 10 markes. When I load the page the map is shown, but markers disappear and the console show me the following error :

Uncaught ReferenceError: google is not defined
at new Location (app.js:60)
at app.js:97

Here is my JS code:

// Initialize Google Map to Florence
var map;

function initialize() {
  var mapOptions = {
    zoom: 12,
    center: new google.maps.LatLng(43.7792500, 11.2462600),
    disableDefaultUI: true
  };
  map = new google.maps.Map(document.getElementById('map'), mapOptions);
}

function mapError() {
  console.log("Issue in retrieving data and resouces. Please, try to reload the page.");
}

// Create Location Class.
var Location = function(title, x, y, foursquare_id) {
  var self = this;
  // Set Location Title.
  this.title = title;

  // Set Location coordinates.
  this.x = x; // Longitude.
  this.y = y; // Latitude.

  // Set Location id from Foursquare.
  this.foursquare_id = foursquare_id;

  // Request 10 most recent comments from Foursquare.
  this.Request = function() {
    var comments = [];
    var foursquare_url = 'https://api.foursquare.com/v2/venues/';
    var request = foursquare_url + self.foursquare_id + '/tips?sort=recent&limit=10&v=20150609&client_id=' + client_id + '&client_secret=' + client_secret;

    // Get Request and Return formatted Data
    $.getJSON(request,
      function(data) {
        $.each(data.response.tips.items, function(i, tips) {
          comments.push('<li>' + tips.text + '</li>');
        });
        // If Request Succeeds.
      }).done(function() {
      self.content = "<fieldset><legend><h1>" + self.title + "</h1></legend><h3>10 Most Recent Comments from Foursquare</h3><ol class='tips'>" + comments.join('') + "</ol><cite>Source: Foursquare Labs, Inc.</cite></fieldset>";
      // If Request Fails.
    }).fail(function(jqXHR, textStatus, errorThrown) {
      self.content = "<fieldset><legend><h1>" + self.title + "</h1></legend><h3>Foursquare says Sorry!</h3><h4>There was a problem in retrieving data from Foursquare. Please, try to reload the page.</h4></fieldset>";
      console.log('getJSON request failed! ' + textStatus);
    });
  }();

  // Initialize Google Maps InfoWindow.
  this.infowindow = new google.maps.InfoWindow();

  // Assign Markers to Locations.
  this.marker = new google.maps.Marker({
    map: map,
    draggable: true,
    animation: google.maps.Animation.BOUNCE,
    position: new google.maps.LatLng(self.x, self.y),
    title: self.title
  });
  self.marker.addListener('click', toggleBounce);

  function toggleBounce() {
    if (self.marker.getAnimation() !== null) {
      self.marker.setAnimation(google.maps.Animation.BOUNCE);
    } else {
      self.marker.setAnimation(google.maps.Animation.BOUNCE);
    }
  }

  // Show Info Window.
  this.openInfowindow = function() {
    for (var i = 0; i < Data.locations.length; i++) {
      Data.locations[i].infowindow.close();
    }
    map.panTo(self.marker.getPosition())
    self.infowindow.setContent(self.content);
    self.infowindow.open(map, self.marker);
  };

  // Click event-listener to each Marker that shows the relative Info Window.
  this.addListener = google.maps.event.addListener(self.marker, 'click', (this.openInfowindow));
};

// Create Location Objects.
var Data = {
  locations: [

    new Location("Palazzo Pitti", 43.765264, 11.250094, "4bc8c9d7af07a593d4aa812d"),
    new Location("Uffizi Gallery", 43.768439, 11.2559, "51191cdfb0ed67c8fff5610b"),
    new Location("Florence Cathedral", 43.773083, 11.256222, "4bd00cdb046076b00a576f71"),
    new Location("Palazzo Vecchio", 43.769315, 11.256174, "4bd01b8077b29c74a0298a82"),
    new Location("Piazza della Signoria", 43.7684152597, 11.2534589862, "4b81729af964a520a7a630e3"),
    new Location("Giotto's Campanile", 43.772772, 11.255786, "4b49cd73f964a520d87326e3"),
    new Location("Piazzale Michelangelo", 43.762462, 11.264897, "4b3276d5f964a520620c25e3"),
    new Location("Ponte Vecchio", 43.768009, 11.253165, "4b6ed35df964a52038cc2ce3"),
    new Location("Boboli Gardens", 43.762361, 11.248297, "4bc97abcfb84c9b6f62e1b3e"),
    new Location("Vinci", 43.783333, 10.916667, "4ca4f0a0965c9c74530dc7fa"),
  ],
  query: ko.observable(''),
};

// Search by name into the locations list.
Data.search = ko.computed(function() {
  var self = this;
  var search = this.query().toLowerCase();
  return ko.utils.arrayFilter(self.locations, function(location) {
    var isMatching = location.title.toLowerCase().indexOf(search) >= 0;
    if (isMatching) {
      Marker.setVisible(true);
    } else {
      Marker.setVisible(false);
    }
    return isMatching;
  });
})

ko.applyBindings(Data);

Here is my HTML code :

<!DOCTYPE html>
<html>

<head>

  <title>Map</title>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1.0">
  <link rel="stylesheet" href="css/styles.css">

</head>

<body>

  <div class="container">
    <div class="row">
      <div class="search" id="search">
        <input class="input" type="text" placeholder="Search..." data- bind="value: query, valueUpdate: 'keyup'">
        <ul class="list" data-bind="template: { name:'location',  foreach:search }"></ul>
      </div>
      <!-- Search Form. -->

      <div class="map" id="map"></div>
      <!-- Google Map. -->
    </div>
    <!-- ROW. -->
  </div>
  <!-- CONTAINER. -->

  <!-- Show list under the search form. -->
  <script type="text/html" id="location">
    <li class="item" data-bind="text: title, click: openInfowindow"></li>
  </script>
  <!-- Import knockout framework, jquery library, personal js and Google   Maps Apis -->
  <script src="js/knockout-3.4.1.js"></script>
  <script src="js/jquery-3.1.1.js"></script>
  <script src="js/app.js"></script>
  <script async defer src="https://maps.googleapis.com/maps/api/js? key=AIzaSyCFSYzAYNIkokmho_gNRE7vWO7-dAZW46g&callback=initialize" onerror="mapError()"></script>
</body>

</html>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
  • 1
    You call initialise as a callback from loading a deferred script. That means you cannot run ANY of the script you have after the initialise function until AFTER the initialise has run. Put all that in a function and call that new function at the end of initialise. Additionally this is a duplicate of MANY answers found by simply searching google for ***Uncaught ReferenceError: google is not defined*** – mplungjan Mar 01 '17 at 09:00
  • I've changed script position but still return the same error. Even if i put the entire js code before the &callback=initialize the same error is displayed on the console and markers do not show –  Mar 01 '17 at 09:19
  • The code that uses ANY google maps API needs to be INSIDE or AFTER the initialise was called. `function initialize() { ............... this.marker = new google.maps.Marker({................}) .....}` – mplungjan Mar 01 '17 at 09:21

0 Answers0