title: Google Maps for Rails - update markers with AJAX
body: <p>I am working on a web app and I use Ruby on Rails. Our index is made of a map and of a search field. You can search a location and the map updates its markers.</p>
  
  <p>I would like to use Ajax to avoid refreshing the page. So I added <code>remote: true</code> to the form, a <code>respond_to</code> in the controller and a new <code>search.js.erb.</code> My <code>search.js.erb</code> renders a partial <code>_googlemap.erb</code> which contains the script to initialize the map. </p>
  
  <p>Here is my problem. As the map already exists, it's like if I wanted to create the same object twice, which of course doesn't work and is awfull. I'd like to update only markers in the map with new ones. But I can't find a way to do it.</p>
  
  <p>I saw the former version of Gmaps4rails integrated a way to do it ( <code>Gmaps.map.replaceMarkers(your_markers_json_array);</code> ) but it doesn't seem to work now. When I use it, I got this error: "<code>TypeError: Gmaps.map is undefined</code>". I tried with "<code>handler.replaceMarkers();</code>" but this time I have "<code>TypeError: handler.replaceMarkers is not a function</code>".</p>
  
  <p>I am new to Javascript and to Rails, but I want to improve my knowledge and I really need to go on with the rest of this web app. I have been looking for a solution everywhere on the internet but in vain.</p>
  
  <p><a href="http://thawing-chamber-1586.herokuapp.com/" rel="nofollow">Live website here</a></p>
  
  <p>Please, could someone tell me how I could do that and what I am doing wrong?</p>
  
  <p>MANY thanks in advance,</p>
  
  <p>Céline</p>
  
  <blockquote>
    <p>zones_controller.rb</p>
  </blockquote>
  
  <pre><code>def search
     respond_to do |format|
       format.html.none do
        search_params = params[:zone][:search]
           coordinates = Geocoder.coordinates(search_params).join(",")
           @zones = Zone.search(
             "", { "aroundLatLng" =&gt; coordinates, 
                    "aroundRadius" =&gt; 500000  #Searches around 500 km
                  })
           if coordinates.nil?
             @zones = Zone.search(params[:search])
           elsif @zones.empty?
             @zones = Zone.all
             flash[:error] = "No zone could be found. Please try again."
           end
         build_map(@zones)
       end
  
       format.js
     end
  end
  
  def build_map(array)
    @hash = Gmaps4rails.build_markers(array) do |zone, marker|
      marker.lat zone.latitude
      marker.lng zone.longitude
      marker.json({ title: zone.description, id: zone.id })
      marker.infowindow render_to_string(:partial =&gt; "/zones/map_box", locals: { zone: zone })
    end
  end
  </code></pre>
  
  <blockquote>
    <p>search.html.erb</p>
  </blockquote>
  
  <pre><code>    &lt;div id="map" style='width: 100%; height: 700px;'&gt;
  &lt;/div&gt;
    &lt;!-- Beginning Google maps --&gt;
  
  &lt;script type="text/javascript" id="map_script"&gt;
     $(document).ready(function() {
       &lt;%= render 'googlemap', hash: @hash %&gt;
     }); // Document ready
  &lt;/script&gt;
  </code></pre>
  
    
  
  <blockquote>
    <p>_googlemap.erb</p>
  </blockquote>
  
  <pre><code>handler = Gmaps.build('Google');
  handler.buildMap({ provider: {
      disableDefaultUI: true,
      mapTypeId: google.maps.MapTypeId.TERRAIN
    }, internal: {id: 'map'}
  }, function(){
    markers_json = &lt;%= raw hash.to_json %&gt;;
    markers = _.map(markers_json, function(marker_json){
  
      marker = handler.addMarker(marker_json);
      handler.getMap().setZoom(4);
  
      _.extend(marker, marker_json);
  
      marker.infowindow = new google.maps.InfoWindow({
        content: marker.infowindow
      });
  
      return marker;
    });
  
    handler.bounds.extendWith(markers);
    handler.fitMapToBounds();
  });
  </code></pre>
  
  <blockquote>
    <p>search.js.erb</p>
  </blockquote>
  
  <pre><code>$('#map_script').replaceWith("&lt;%= render 'googlemap', hash: @hash %&gt;");
  </code></pre>