ga-wdi-boston / capstone-project

Other
3 stars 29 forks source link

Google maps integration #852

Closed jbculbertson closed 6 years ago

jbculbertson commented 6 years ago

I've got a bit of a unique problem - in my project, I'm integrating google maps API. I've got a big hairy function called initialize that basically starts up google maps at a predetermined point.

I had it working perfectly - you could toggle away from the map, and back, and it would re-initialize correclty.

Now I've added additional code to allow for a search box to be within the map. This code goes within the initialize function. It works fine, until you toggle away, then try to come back. It errors out, saying it cannot read property value null of undefined.

I'd love it if someone could help me debug this. I'm having trouble using my inspector to even get closer to the issue.

Big hairy function below:

const initialize = function (pos) {
  console.log('fires within initialize')
  $('#display').empty()
  const showMapHtml = showMapTemplate()
  $('#display').append(showMapHtml)
  GoogleMapsLoader.load(function (google) {
// this section clears the map on load - needed due to a bug that happened when
// you had a map with markers, and then clicked to a new tab.  When you re-init the
// map it wouldn't let you add polyline.
    markers = []
    route = []
    polyline = new google.maps.Polyline({
      strokeColor: 'black',
      strokeWeight: 3,
      map: map
    })
    console.log('fires within GoogleMapsLoader1')
    const mapOptions = {
      zoom: 15,
      center: pos,
      mapTypeId: 'terrain',
      gestureHandling: 'cooperative'
    }
    console.log('fires within GoogleMapsLoader1')
    const map = new google.maps.Map(document.getElementById('map'),
    mapOptions)
    polyline = new google.maps.Polyline({
      strokeColor: 'black',
      strokeWeight: 3,
      map: map
    })
    //
    //
    console.log('fires within GoogleMapsLoader3')
    const input = document.getElementById('pac-input')
    console.log('fires within GoogleMapsLoader4')
    const searchBox = new google.maps.places.SearchBox(input)
    console.log('fires within GoogleMapsLoader5')
    map.controls[google.maps.ControlPosition.TOP_LEFT].push(input)
    console.log('fires within GoogleMapsLoader6')
    map.addListener('bounds_changed', function () {
      searchBox.setBounds(map.getBounds())
    })
    searchBox.addListener('places_changed', function () {
      const places = searchBox.getPlaces()
      if (places.length === 0) {
        return
      }
    // For each place, get the icon, name and location.
      const bounds = new google.maps.LatLngBounds()
      places.forEach(function (place) {
        if (place.geometry.viewport) {
          bounds.union(place.geometry.viewport)
        } else {
          bounds.extend(place.geometry.location)
        }
      })
      map.fitBounds(bounds)
    })
//
//
    google.maps.event.addListener(map, 'click', function (event) {
      addPoint(event.latLng)
    })
    function removePoint (marker) {
      console.log('fires within RemovePoint')
      for (let i = 0; i < markers.length; i++) {
        if (markers[i] === marker) {
          markers[i].setMap(null)
          markers.splice(i, 1)
          route.splice(i, 1)
          polyline.getPath().removeAt(i)
        }
      }
      length = google.maps.geometry.spherical.computeLength(polyline.getPath())
      mileLength = (length * 0.000621371).toFixed(2)
      $('#distance-input').val(mileLength)
      $('#distance-input').css('background', 'linear-gradient(to right, #fffbd5, #b20a2c)')
      setTimeout(function () {
        $('#distance-input').css('background', 'white')
      }, 1000)
    }
    function addPoint (latlng) {
      console.log('fires within AddPoint, latlng is ', latlng)
      const marker = new google.maps.Marker({
        position: latlng,
        animation: google.maps.Animation.DROP,
        map: map
      })
      const x = latlng.lat()
      const y = latlng.lng()
      route.push([x, y])
      markers.push(marker)
      polyline.getPath().setAt(markers.length - 1, latlng)
      google.maps.event.addListener(marker, 'click', function (event) {
        removePoint(marker)
      })
      length = google.maps.geometry.spherical.computeLength(polyline.getPath())
      mileLength = (length * 0.000621371).toFixed(2)
      $('#distance-input').val(mileLength)
      $('#distance-input').css('background', 'linear-gradient(to right, #dce35b, #45b649)')
      setTimeout(function () {
        $('#distance-input').css('background', 'white')
      }, 1000)
      console.log('Total miles is ' + mileLength)
    }
    // clearBoard 'function'
    $(document).ready(function () {
      $('#clear-button').on('click', function (event) {
        console.log('fires within ClearRoute (which is not actually a function)')
        for (let i = 0; i < markers.length; i++) {
          console.log('Markers within clearRoute forLoop ' + i + markers[i])
          markers[i].setMap(null)
        }
        polyline.setMap(null)
        markers = []
        route = []
        mileLength = 0
        polyline = new google.maps.Polyline({
          strokeColor: 'black',
          strokeWeight: 3,
          map: map
        })
        $('#distance-input').val(mileLength)
        $('#distance-input').css('background', 'linear-gradient(to right, #fffbd5, #b20a2c)')
        setTimeout(function () {
          $('#distance-input').css('background', 'white')
        }, 1000)
        console.log('Total miles is ' + mileLength)
      })
    })
  })
}
jbculbertson commented 6 years ago

Scotty Scripts led me down the right road here. My issue was that they way my app was setup, everytime I clicked away from the map, I was .emptying the div that contained it.

To fix, I moved the map HTML from handlebars to index.html. And when I click away, its just hiding it. In addition, instead of running initialize everytime the map button is clicked, after the first click, I'm just showing the map vs re-initializing.

Should be all set - thanks Scott!