Sort by distance is not working, screen shows a "loading spinner" page


#1

Sort is done on server level while rest on template. Im also using simple:reactive-method. Router for the page does not have a waitOn code.

I did a console.log on currentLocation.lng/lat and it registers values. Im not sure how else i can troubleshoot it.

Template stuff

Template.nearPosts.onRendered(function () {  
  var currentLocation = Geolocation.latLng() || '';
	  if(currentLocation) {
	  	Session.set('lat', currentLocation.lat); 
	    Session.set('lng', currentLocation.lng);
	  }
});
Template.nearPosts.helpers({
	nearPosts: function () {
    return ReactiveMethod.call("getPosts", Session.get("lat"), Session.get("lng"));
  }
});

Server stuff

  Meteor.methods({ 
    getPosts: function (lat, lng) {
      check(lat, Number); 
      check(lng, Number); 

      return Posts.find({
        loc: { 
          $near: {
            $geometry: { 
              type: "Point",      
              coordinates: [lng, lat]
            }, 
            $maxDistance: 500
          }

#2

First try it with values set by hand.
Than set lat+lng as Session.set(‘location’, {lat: currentLocation.lat, lng: currentLocation.lng}) to not run it 2x (once for every variable change).
And do not use that helper till that ‘location’ Session have correct values


#4

Thanks for the quick reply.
I inserted fixed values into Session.set and Session.get. However the page still shows a loading spinner. Also I use “loc” in the server js, should I use it to replace “location” in the template code?

The funny thing is that the first time i click on the link to page, it would show undefined lng/lng and will not resolve those values unless i click home, and then back to the page link.


#5

Make sure you are indexing your collection as a “2dsphere”. I had this same problem a few weeks ago and this code fixed it.

Collection._ensureIndex({‘loc’:‘2dsphere’});

loc being the name of the value storing my coordinates.

EDIT: make sure that code is in the code you are using the publish the database.


#6

Thanks! But doesnt work with or without the sphere index code. However the server did not throw an error this time round so I suspect the issue probably lies on the template side.


#7

@mthh: Could you provide some more code, please. I see something “odd” - I’m not sure what you’re trying to do here:

var currentLocation = Geolocation.latLng() || '';

An object, even an empty object {} evaulates as “truthy”, so if Geolocation.latLng is always an object. it will never evaluate the result as '' (falsey). Conversely, if Geolocation.latLng does evaluate as “falsey”, there is no point evaluating as '' … we need to see more of Geolocation.

There is no (obvious) reactivity in the code which Session.sets lat and long, so it will only ever run once per template instance (which may be expected - I don’t know what your expectation is).

This:

return ReactiveMethod.call("getPosts", Session.get("lat"), Session.get("lng"));

is a little concerning. There is/was an issue with potential infinite loops in ReactiveMethod. @sashko recommends mnmtanish:call for this issue. I believe @msavin also has a package for this.

Can we see your “standard sorting logic”?

loc: { // standard sorting logic}, 
  $maxDistance: 500  ....

@ipbyrne is correct: you do need a Collection._ensureIndex({'loc':'2dsphere'});, but you only really need this once (it’s set on the actual MongoDB collection) - a good compromise is in your server’s Meteor.startup(). If it’s in the publication it will get re-evaluated each time the collection changes (not an expensive operation past the first occurrence, but still worth avoiding).

Routing - I haven’t used iron:router, so can’t really offer anything there.


#8

@robfallows Thanks for the reply. Have added the logic as requested.

The idea is not let the geolocation run non stop, just once when the user clicks on the page, gets sent to sort and that will be all. No constant monitoring and constant sorting.