0

i'm rather new to Meteor and have a problem, where can't figure out how to solve it.

I want to store dates in a collection. I can pickup the place of the meeting using google maps, which gives me a String with the coordinates. I reverse geocode the coordinates with jaymc:google-reverse-geocode which is basically working (i can console.log the results).

When using Session variables i can output the result, but they keep changing itself. The entrys get there result, then first and second entry change their result, then they change again and so on.

I tried to use ReactiveVar and ReactiveDict but with no result. I can't get any results returned from the reverseGeocode function.

Here's the code:

{{#each termine}}
   <div class="listTermine">
   <p class="title">{{title}}</p>
   <p class="desc">{{desc}}</p>
   <p class="location">{{getAddress}}</p>
   <p class="dates">
   <span class="glyphicon glyphicon-time" aria-hidden="true"></span>
  {{formatDate startDate}} bis {{formatDate endDate}}
  </p>
</div>
{{/each}}


Template.showTermine.helpers({
    getAddress: function() {
        var locArray = Termine.findOne({
            "title": this.title
        }, {
            fields: {
                locations: 1
            }
        });
        latlngArray = locArray.locations.toString();
        var latlong = latlngArray.split(",");
        var lat = latlong[0];
        var lng = latlong[1];
        reverseGeocode.getLocation(lat, lng, function(location) {
                Session.set('location', reverseGeocode.getAddrStr());
            })
            // commented out to prevent infinite loop
            //return Session.get('location');
    }
});
46and2
  • 1
  • 1

2 Answers2

1

this is because a Reactive variable (like a Session variable) will cause the whole function it is included in to re-run each time it is changed.

So here you have the Session.set() in the same function as the Session.get(), so it will re-run the getAddress function each time Session.set() is called, which will re-run the thing in a loop.

Since you're returning the result in the same function, you really don't need a Session variable at all here:

you can simply:

reverseGeocode.getLocation(lat, lng, function(location) {
                return reverseGeocode.getAddrStr();
            })

if this doesn't work (because you're doing an asynchronous call to .getLocation), then you should do this call somewhere else

The best place to do this would be in the Template.mytemplate.onCreated() event

Template.showTermine.onCreated(function() {
        var locArray = Termine.findOne({
            "title": this.title
        }, {
            fields: {
                locations: 1
            }
        });
        latlngArray = locArray.locations.toString();
        var latlong = latlngArray.split(",");
        var lat = latlong[0];
        var lng = latlong[1];
        reverseGeocode.getLocation(lat, lng, function(location) {
                Session.set('location', reverseGeocode.getAddrStr());
        })});

Template.showTermine.helpers({
  "getAddress": function() {
     return Session.get("location");
  }
});
MrE
  • 19,584
  • 12
  • 87
  • 105
  • thanks for your answers! Everything makes sense, except for the mongo query. Theres `this.title` included, this works like it should in the helper function. Whats the best practice to fetch the data? I tried to get the date in the helper function and pass it to the onCreated function, but that didnt seem to work. – 46and2 May 17 '16 at 07:37
0

The set is called inside the callback which will execute after the helper has returned the get already, this mean when it sets the variable the helper gets invalidated because of the change in the session value and reruns.

Couple of possible fixes: Move code to set the var into the onCreated or onRendered methods and remove everything bar the return from your helper

Or Ensure the session var is created as a null value initially and then add an if check to look at the value of the var before attempting to call the location service or set the var.

Reactive vars are defo the right way to go over sessions for repeated templates here to avoid namespace collisions in session and the same advice should work for reactive vars or sessions vars. Just avoid setting and getting anything reactive in the same helper without some checks to see if it is needed

Philip Pryde
  • 930
  • 7
  • 13