apneadiving / Google-Maps-for-Rails

Enables easy Google map + overlays creation in Ruby apps
https://apneadiving.github.io/
MIT License
2.27k stars 382 forks source link

Uncaught TypeError: Cannot read property 'addMarker' of undefined #546

Closed thebatu closed 7 years ago

thebatu commented 7 years ago

the issue is not produced on first page load, map works correcrly at first, but after a an ajax call the map gives the below error in (check.js.erb) any idea why this error is produced, and how to fix it?

the code https://github.com/thebatu/escapin_city. Using latest version of the gem.

    Uncaught TypeError: Cannot read property 'addMarker' of undefined
    at Handler.Gmaps.Objects.Handler.Handler.addMarker 
    at Function._.map._.collect
    at Handler.Gmaps.Objects.Handler.Handler.addMarkers
    at eval (eval at <anonymous> 
    at tg.<anonymous>
    at tg.<anonymous>
    at _.B.trigger
    at common.js:27
    at Hx.G (map.js:31)
      Handler.prototype.addMarker = function(marker_data, provider_options) {
      var marker;
      marker = this._builder('Marker').build(marker_data, provider_options, this.marker_options);
      marker.setMap(this.getMap());
      this.clusterer.addMarker(marker);  //cluster has no addMarker
      return marker;
    };

Below is the code relevent code:- hunts#play creates an initial map. if click on verify position link the hunts#check re-creates a map in check.js.erb with new markers


hunts_controller:-
def play
    @checkpoint = @hunt.checkpoints.first
    @hash = Gmaps4rails.build_markers(@checkpoint) do |check, marker|
      marker.lat check.lat
      marker.lng check.log
    end
  end

  def check
    checkpoint_id = params[:check][:checkpoint_id]
    @current_checkpoint = Checkpoint.find(checkpoint_id)

    latitude = params[:check][:latitude]
    longitude = params[:check][:longitude]
    accuracy = params[:check][:accuracy]

    loc_nav = [latitude, longitude]
    loc_checkpoint = [@current_checkpoint.lat , @current_checkpoint.log ]

    distance = Geocoder::Calculations.distance_between(loc_nav,loc_checkpoint)

    if (distance + accuracy.to_f) > 70 # 70 supposed min distance to treasure
      @checkpoint = @current_checkpoint.lower_item
    else
      @checkpoint = @current_checkpoint
    end
    @hash = Gmaps4rails.build_markers(@checkpoint) do |check, marker|
      marker.lat check.lat
      marker.lng check.log
    end
  end
**play.html.erb**

<div class="container">
<%= simple_form_for :check, url: check_hunt_path(@hunt), method: :post, remote: true, html: { id: "check-form" } do |f| %>
  <%= f.input :checkpoint_id, input_html: { value: @checkpoint.id }, :as => :hidden %>
  <%= f.input :latitude , :as => :hidden%>
  <%= f.input :longitude, :as => :hidden%>
  <%= f.input :accuracy ,:as => :hidden%>
  <%= f.submit 'verify' %>
<% end %>

<div id="hunt-content">
  <%= render 'hunt_content', hunt: @hunt, checkpoint: @checkpoint %>
</div>

<% content_for(:after_js) do %>
  <script>
    $(document).ready(function() {
      var handler = Gmaps.build('Google');
      handler.buildMap({ internal: { id: 'map' } }, function() {
        markers = handler.addMarkers(<%= raw @hash.to_json %>);
        handler.bounds.extendWith(markers);
        handler.fitMapToBounds();
        if (markers.length == 0) {
          handler.getMap().setZoom(2);
        } else if (markers.length == 1) {
          handler.getMap().setZoom(2);
        }
      });
    });
  </script>
<% end %>
</div>
**_hunt_content.html.erb**
</div>
  <div id="map"></div>
<div>
**check.js.erb**

$('#hunt-content').html("<%= j render 'hunt_content', hunt: @hunt, checkpoint: @checkpoint %>")

var handler = Gmaps.build('Google');
handler.buildMap({ internal: { id: 'map' } }, function() {
  markers = handler.addMarkers(<%= raw @hash.to_json %>);
  handler.bounds.extendWith(markers);
  handler.fitMapToBounds();
  if (markers.length == 0) {
    handler.getMap().setZoom(2);
  }
  else if (markers.length == 1) {
    handler.getMap().setZoom(2);
  }
});

// update checkoint_id field
$('#check_checkpoint_id').val(<%= @checkpoint.id %>)
**application.js**

(function(){
  var options = {
    enableHighAccuracy: true,
    timeout: 5000,
    maximumAge: 0
  };

  $('body').on('ajax:before', '#check-form', function(e){
    e.preventDefault();
    navigator.geolocation.getCurrentPosition(success, error, options);
  });