Meteor template helper conditional returns false c

2019-05-09 00:39发布

问题:

Im very new to Meteor but so far Im really enjoying coding on the platform. I have come up against a bit of hurdle and cant seem to find the correct way. I want to create a helper function that will check lat and long and check it against some predefined range if it falls in between these it returns true.

I have included the code I currently have:

Template.header.helpers({
 locationCheck: function() {
    navigator.geolocation.getCurrentPosition(success_callback,error_callback);

    function success_callback(p){
        // Building Latitude = 51.522206
        // Building Longitude = -0.078305
        var lat = parseFloat(p.coords.latitude);
        var lon = parseFloat(p.coords.longitude);
        console.log('Latitude: '+lat);
        console.log('Longitiude: '+lon);

      if( lat >= 51.521606 && lat <= 51.522606 && lon >= -0.078805  && lon <=  -0.077705 ) {
        console.log('you are in the area');
        return 1;
      } else {
        console.log('you are not in the area');
        return 0;
      }
    }

    function error_callback(p){
         return 0;
    }
 }
});

And in my template I want to use the return value in a handlebars if statement, like so:

  {{#if locationCheck}}
        {{loginButtons}}
  {{else}}
        <p>Your are out of the vicinity</p>
  {{/if}}

The problem is it is consistently return the else statement result even though in the console it is returning this you are in the area.

Any help would be awesome.

Thanks in advance.

回答1:

This is because of the callback pattern. The helpers would have already returned undefined by the time the callbacks return data. You need to use synchronous javascript inside helpers, and if having an asynchronous operation use reactive Meteor Session hashes to relay the data through:

Template.header.helpers({
    locationCheck: function() {
        return Session.get("locationCheck");
    },
    isLoading:function() {
        return Session.equals("locationCheck",null); 
    }
});

Then in your header when the template is created you can fire the check off:

Template.header.created = function() {
    navigator.geolocation.getCurrentPosition(success_callback,error_callback);

    function success_callback(p){
        // Building Latitude = 51.522206
        // Building Longitude = -0.078305
        var lat = parseFloat(p.coords.latitude);
        var lon = parseFloat(p.coords.longitude);
        console.log('Latitude: '+lat);
        console.log('Longitiude: '+lon);

      if( lat >= 51.521606 && lat <= 51.522606 && lon >= -0.078805  && lon <=  -0.077705 ) {
        console.log('you are in the area');
        Session.set("locationCheck",1);
      } else {
        console.log('you are not in the area');
        Session.set("locationCheck",0);
      }
    }

    function error_callback(p){
         return 0;
    }
}

As soon as Session.set("locationCheck",1) (or 0) is set the template will be re-rendered with the new data.

You can use the isLoading helper while its capturing the location:

<template name="header">
    {{#if isLoading}}
    Loading
    {{else}}
        {{#if locationCheck}}
            {{>template1}}
        {{else}}
            {{>template0}}
        {{/if}}
    {{/if}}
</template>

<template name="template0">
    <p>Denied</p>
</template>

<template name="template1">
    Approved
</template>