Search code examples
ruby-on-railsgmaps4rails

Empty google map when rendering


I am building a new test app following exactly the steps from https://github.com/apneadiving/Google-Maps-for-Rails. Don't know why I am getting rendered only an empty frame, no map, no markers.

Here is a snapshot of my code.

application.html.erb

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My New Google Maps Rails App</title>
    <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track' => true %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>

    <script src="https://maps.google.com/maps/api/js?v=3.23&amp;libraries=geometry;&amp;key=AIzaSyAncOJnAgKEjrv2PY__Z0gYy3zJyTznUQ0" type="text/javascript"></script>
    <script src="https://cdn.rawgit.com/googlemaps/v3-utility-library/master/markerclustererplus/src/markerclusterer_packed.js" type="text/javascript"></script>
    <script src="https://cdn.rawgit.com/googlemaps/v3-utility-library/master/richmarker/src/richmarker-compiled.js" type="text/javascript"></script>
    <script src="https://cdn.rawgit.com/googlemaps/v3-utility-library/master/infobox/src/infobox_packed.js" type="text/javascript"></script>

    <%= csrf_meta_tags %>
  </head>
  <body>
    <div class="container-fluid">
      <div class="row-fluid">
        <%= render 'layouts/messages' %>
      </div>
      <%= yield %>
    </div>
  </body>
</html>

application.js

//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require underscore
//= require gmaps/google
//= require bootstrap-sprockets
//= require_tree .

items_controller.rb - the index method

  def index
    @items = Item.order(updated_at: :desc, created_at: :desc)
    @hash = Gmaps4rails.build_markers(@items) do |item, marker|
      marker.lat 43.70676484
      marker.lng -79.39831068
      marker.infowindow "TEST"
    end
  end

the Java scrip code in the file gmaps.js

handler = Gmaps.build('Google');
handler.buildMap({
    provider: {
      disableDefaultUI: true
      // pass in other Google Maps API options here
    },
    internal: {
      id: 'map'
    }
  },
  function(){
    markers = handler.addMarkers(markers);
    handler.bounds.extendWith(markers);
    handler.fitMapToBounds();
  }
);

and finally the index.html.erb file for items

<h1>Items Index</h1>

<!--<p id="notice"><%= notice %></p>-->

<h3>Listing Items</h3>

<table class="table table-striped table-bordered table-hover table-condensed table-responsive">
  <thead>
    <tr>
      <th colspan="4" style="text-align: center">Actions</th>
      <th style="text-align: center">ID</th>
      <th style="text-align: center">Item ID</th>
      <th style="text-align: center">Item Name</th>
      <th style="text-align: center">Created At</th>
      <th style="text-align: center">Updated At</th>
    </tr>
  </thead>

  <tbody>
    <% @items.each do |item| %>
      <tr>
        <td><%= link_to 'Show', item %></td>
        <td><%= link_to 'Edit', edit_item_path(item) %></td>
        <td><%= link_to 'Destroy', item, method: :delete, data: { confirm: 'Are you sure?' } %></td>
        <td><%= link_to 'GET-Update', [:get_update, item] %></td>
        <td><%= item.id %></td>
        <td><%= item.item_id %></td>
        <td><%= item.item_name %></td>
        <td><%= item.created_at %></td>
        <td><%= item.updated_at %></td>
      </tr>
    <% end %>
  </tbody>
</table>

<br>

<div class="row-fluid">
  <div id="map" style='width: 100%; height: 500px; border: 1px solid black;'></div>
</div>

<br>

<%= link_to 'New Item', new_item_path %> |
<%= link_to 'Home', '/' %>

<script type="text/javascript">
  markers = handler.addMarkers(<%=raw @hash.to_json %>);
</script>

Don't know what I am doing wrong here?

Also, I don't think lat and lng are set correctly in the addMarkers method. Don't think the values from the controller are passed to the method.


Solution

  • I changed the index method in the 'items_controller.rb` this way:

    def index @items = Item.order(updated_at: :desc, created_at: :desc)

    @hash = Gmaps4rails.build_markers(@items) do |item, marker|
      marker.lat item.lat || 51.497731
      marker.lng item.lng || -0.136023
      marker.infowindow item.item_name + " " + item.item_id
      title = item.item_id
      marker.json({:title => title})
    end
    

    end

    Changed the script in the page index.html.erb this way:

    <script type="text/javascript">
      buildMap (<%=raw @hash.to_json %>);
    </script>
    

    Replaced the file gmaps.js with the file gmaps_google.js.coffee (replaced a Java Script with a coffee script:

    class RichMarkerBuilder extends Gmaps.Google.Builders.Marker #inherit from builtin builder
      #override create_marker method
      create_marker: ->
        options = _.extend @marker_options(), @rich_marker_options()
        @serviceObject = new RichMarker options #assign marker to @serviceObject
    
      rich_marker_options: ->
        marker = document.createElement("div")
        marker.setAttribute 'class', 'marker_container'
        marker.innerHTML = @args.title
        _.extend(@marker_options(), { content: marker })
    
      infobox: (boxText)->
        content: boxText
        pixelOffset: new google.maps.Size(-140, 0)
        boxStyle:
          width: "300px"
    
      # override method
      create_infowindow: ->
        return null unless _.isString @args.infowindow
        boxText = document.createElement("div")
        boxText.setAttribute("class", 'marker_info_box') #to customize
        boxText.innerHTML = @args.infowindow
        @infowindow = new InfoBox(@infobox(boxText))
    
    @buildMap = (markers)->
        handler = Gmaps.build 'Google', { builders: { Marker: RichMarkerBuilder} } #dependency injection
    
        #then standard use
        handler.buildMap { provider: {}, internal: {id: 'map'} }, ->
          markers = handler.addMarkers(markers)
          handler.bounds.extendWith(markers)
          handler.fitMapToBounds()
    

    And after all these changes the map is correctly rendered with items.