apneadiving / Google-Maps-for-Rails

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

replaceMarkers not working in 1.0.2 #83

Closed Kosmas closed 13 years ago

Kosmas commented 13 years ago

Having upgraded from 0.11 to 1.0.2, the replaceMarkers function does not work.

I'm using the last position to update the marker.

When there is no update in the last position there is no error in the function.

If there is an update then the following error is displayed:

marker.serviceObject is undefined marker.seviceObject.setMap(null);

Have tried with the addMarkers and seems to be working fine:

The code used, which is defined below the actual map creation in the view is the following:

<% content_for :scripts do -%>
    <script type="text/javascript" charset="utf-8">
      $(function() { setInterval(function(){$.getJSON("/gps_positions.json", function(data){
        Gmaps.map.replaceMarkers(data);
        })},30000)});
    </script>
apneadiving commented 13 years ago

Basically, markers is an array containing marker object. Marker contains the value from the json + a serviceObject which is created by the map provider.

In your case, it seems one marker doesn't have any serviceObject which means it isn't displayed on the map.

Could you please check why the marker has no serviceObject, ie what's the sequence leading to this situation?

I'll re-add the if condition on serviceObject existence, I simply hope there not a deeper bug here.

apneadiving commented 13 years ago

ok found out one bug, but didn't have the same error message. I'm gonna release 1.1.1, please tell me if it's ok.

walter commented 13 years ago

Hi,

I'm encountering something similar using 1.1.2 version of the gem on Safari (haven't tried another browser yet). Here's the background code:

// in dragend listener triggered function, update marker with out new latValue and lngValue var newMarkers = [{\"lng\":latValue,\"description\":\"blah\", \"lat\":lngValue, \"draggabel\": true}]

gmaps4RailsMap.replaceMarkers(newMarkers);

The dragged marker disappears as expected at dragend, but no new marker is shows up visibly. However if I go to the console I can see the map has the marker and it has a serviceObject:

Gmaps.still_image_extended_content_values_location_map_div.markers[0] Object description: "blah" draggabel: true lat: 175.22250520833302 lng: -37.789144699240445 serviceObject: W _e3: Object __gm_id: 80 b: null draggable: true gmaccessors: Object map: null position: P q: false title: null visible: false ...

However, the map attribute in the serviceObject is null and the visible attribute is false. I've tried manipulating these attributes with showMarkers() and serviceObject.setMap(Gmaps.still_image_extended_content_values_location_map_div.map), but the marker still doesn't appear.

Been trying to get this to work for most of today, would appreciate it if this gets fixed!

apneadiving commented 13 years ago

@walter: this time I'm pretty sure of my code + I've tests + I've sample app with a sample to check inside the browser (I did with safari too).

Well, I could be wrong, but I'm still wondering if you don't have a closure problem here.

Could you copy paste your whole code in a gist?

walter commented 13 years ago

Hi,

Here's everything involved:

https://gist.github.com/1202775

The most relevant function definition is at line 64.

Thanks for looking into this.

Cheers, Walter

On Sep 8, 2011, at 6:14 PM, Benjamin Roth wrote:

@walter: this time I'm pretty sure of my code + I've tests + I've sample app with a sample to check inside the browser (I did with safari too).

Well, I could be wrong, but I'm still wondering if you don't have a closure problem here.

Could you copy paste your whole code in a gist?

Reply to this email directly or view it on GitHub: https://github.com/apneadiving/Google-Maps-for-Rails/issues/83#issuecomment-2036989

apneadiving commented 13 years ago

Wow, ok I'll look at it in the next 24 hours :)

Just to be sure: have you tried to call replaceMarkers directly from js console in browser?

walter commented 13 years ago

Hi again,

Ok, yeah, gave that a go. Here's what I did:

var newMarkers = [{"lng": -37.789144699240445, "description": 'blart', "lat": 175.31039583333302, "draggabel": true}];

Gmaps.still_image_extended_content_values_location_map_div.replaceMarkers(newMarkers);

The marker disappeared, but no new marker took its place. I did a little further inspection from the console:

Gmaps.still_image_extended_content_values_location_mapdiv.markers[0] Object • description: "blart" • draggabel: true • lat: 175.31039583333302 • lng: -37.789144699240445 • serviceObject: W • **e3: Object • __gm_id: 407 • b: null • draggable: true • gmaccessors: Object • map: null • position: P • q: false • title: null • visible: false • __proto: W • proto**: Object

Same map null and visible false as before.

Best, Walter


Walter McGinnis Kete Project Lead (http://kete.net.nz) Katipo Communications, Ltd. (http://katipo.co.nz) http://twitter.com/wtem +64211241794

On Sep 8, 2011, at 6:40 PM, Benjamin Roth wrote:

Wow, ok I'll look at it in the next 24 hours :)

Just to be sure: have you tried to call replaceMarkers directly from js console in browser?

Reply to this email directly or view it on GitHub: https://github.com/apneadiving/Google-Maps-for-Rails/issues/83#issuecomment-2037134

apneadiving commented 13 years ago

Just edited your gist (untested though). I guess you indeed have a closure problem.

Kosmas commented 13 years ago

Just tried with the new version but have the same error and below is the full description. Not sure where or what I should be looking at but if you have an idea would be great

clearMarker(marker=Object { lng="8.5155", lat="47.3768"})gmaps4...maps.js (line 191)
marker = Object { lng="8.5155", lat="47.3768"}
clearMarkers()gmaps4...maps.js (line 173)
replaceMarkers(new_markers=[Object { lng="8.5155", lat="47.3768"}, Object { lng="8.5155", lat="46.3768"}, Object { lng="8.5155", lat="46.2768"}, 10 more...])gmaps4...base.js (line 373)
new_markers = [Object { lng="8.5155", lat="47.3768"}, Object { lng="8.5155", lat="46.3768"}, Object { lng="8.5155", lat="46.2768"}, 10 more...]
(?)(data=[Object { lng="8.5155", lat="47.3768"}, Object { lng="8.5155", lat="46.3768"}, Object { lng="8.5155", lat="46.2768"}, 10 more...])gps_positions (line 189)
data = [Object { lng="8.5155", lat="47.3768"}, Object { lng="8.5155", lat="46.3768"}, Object { lng="8.5155", lat="46.2768"}, 10 more...]
resolveWith(context=Object { url="/gps_positions.json", isLocal=false, more...}, args=[[Object { lng="8.5155", lat="47.3768"}, Object { lng="8.5155", lat="46.3768"}, Object { lng="8.5155", lat="46.2768"}, 10 more...], "success", Object { readyState=4, responseText="[{"lng": "8.5155", "lat...55", "lat": "46.3768"}]", more...}])jquery...4799549 (line 1008)
context = Object { url="/gps_positions.json", isLocal=false, more...}
args = [[Object { lng="8.5155", lat="47.3768"}, Object { lng="8.5155", lat="46.3768"}, Object { lng="8.5155", lat="46.2768"}, 10 more...], "success", Object { readyState=4, responseText="[{"lng": "8.5155", "lat...55", "lat": "46.3768"}]", more...}]
done(status=200, statusText="success", responses=Object { text="[{"lng": "8.5155", "lat...55", "lat": "46.3768"}]"}, headers="Content-Type: applicati...MT\nContent-Length: 481\n")jquery...4799549 (line 7168)
status = 200
statusText = "success"
responses = Object { text="[{"lng": "8.5155", "lat...55", "lat": "46.3768"}]"}
headers = "Content-Type: applicati...MT\nContent-Length: 481\n"
callback(_=readystatechange , isAbort=undefined)jquery...4799549 (line 7947)
_ = readystatechange
isAbort = undefined
```ruby
apneadiving commented 13 years ago

@Kosmas: could you please show me your code?

Kosmas commented 13 years ago

Sure thing:

Controller:

  respond_to :json, :html

  def index
    @gps_positions = GpsPosition.find(:all)
    @gps_positions_json = @gps_positions.to_gmaps4rails

    @last_position = GpsPosition.last

    respond_with @gps_positions_json
  end

and the view :

<% if @gps_positions.empty? %>
  <p>no entries found</p><br/>
<% else %>

  <!--<div id="map">-->
    <%= gmaps("map_options" => {"zoom" => 9, 
                                "center_longitude" => @last_position.lng, 
                                "center_latitude" => @last_position.lat,
                                "auto_adjust" => false,
                                "auto_zoom" => false},
              "markers" => {"data" => @gps_positions_json}) %>
  <!--</div> -->
    <% content_for :scripts do -%>
      <script type="text/javascript" charset="utf-8">
        $(function() { setInterval(function(){$.getJSON("/gps_positions.json", function(data){
          Gmaps.map.replaceMarkers(data);
        })},30000)});
      </script>
    <% end -%>

  <div class="table">
    <table>
      <th>Latitude</th>
      <th>Longitude</th>
      <th>Created at</th>
      <% for gps_position in @gps_positions %>
        <tr class="<%= cycle('list_line_odd', 'list_line_even') %>">
          <td><%=h gps_position.lat %></td>
          <td><%=h gps_position.lng %></td>
          <td><%=h render_datetime(gps_position.created_at) %></td>
        </tr>
      <% end %>
    </table>
  </div>
<% end %>
apneadiving commented 13 years ago

Ok. As you described earlier, the marker itself isn't even created.

So serviceObject is null and clearMarker fails...

I could check serviceObject existence before trying to clear. That would solve the problem. Yet I can't understand why some of your markers aren't processed. I guess it's linked to the setInterval function but am not sure.

To conclude, the problem is not from replaceMarkers but from clearMarker working on an invalid set of data.

apneadiving commented 13 years ago

To be more precise, you shouldn't set an absolute timeout, but a relative one: the json calls could be long and this mess things up.:

...

So you should wait for the end of the first call + process, then wait for some time, then retrigger the call:

apneadiving commented 13 years ago

(Bascially, I suggest you use setTimeout). http://www.w3schools.com/js/js_timing.asp