Steve Jackson
Steve Jackson

Reputation: 81

Meteor.js reactive html5 geolocation position.coords

I'm a meteor.js nuub, but I did spend quite a bit of time trying to figure this one out.

I'm trying to reactively update my UI based on the HTML5 geolocation API callback passed into getCurrentPosition. However, the UI is not updating with my current code.

Can you offer suggestions and/or a solution? Here are the details:

Basics: meteor server is running, serving other data to/from mongo via collections successfully

I have a main page (main.html):

<head>
  <title>Geolocation</title>
</head>
<body>
<div class="container">
  <header class="navbar">
    <div class="navbar-inner">
      <a class="brand" href="/">Geolocation</a>
    </div>
  </header>
  <div id="locationDemo">
    {{> location}}
  </div>
</div>
</body>

that references a template (location.js):

<template name="location">
  <div>
    Lat: {{lat}}
  </div>
  <div>
    Lon: {{lon}}
  </div>
</template>

that has this associated helper (location.js):

_lat = {
  current: 0,
  dep: new Deps.Dependency,
  get: function(){
    this.dep.depend();

    if(this.current === 0){
      getLocation();
    }

    return this.current;
  },
  set: function(value){
    this.current = value;
    this.dep.changed();
    Deps.flush();
    return this.current;
  }
};

_lon = {
  current: 0,
  dep: new Deps.Dependency,
  get: function(){
    this.dep.depend();

    if(this.current === 0){
      getLocation();
    }

    return this.current;
  },
  set: function(value){
    this.current = value;
    this.dep.changed();
    Deps.flush();
    return this.current;
  }
};

function getLocation(){
  if (navigator.geolocation)
  {
    navigator.geolocation.getCurrentPosition(showPosition, showError);
  }
  else{
    console.log("Geolocation is not supported by this browser.");
  }
}

function showPosition(position)
{
  _lat.set(position.coords.latitude);
  _lon.set(position.coords.longitude);
}

function showError(error) {
  switch(error.code) {
    case error.PERMISSION_DENIED:
      console.log("User denied the request for Geolocation.");
      break;
    case error.POSITION_UNAVAILABLE:
      console.log("Location information is unavailable.");
      break;
    case error.TIMEOUT:
      console.log("The request to get user location timed out.");
      break;
    case error.UNKNOWN_ERROR:
      console.log("An unknown error occurred.");
      break;
  }
}

Template.location.helpers({
  lat: _lat.get(),
  lon: _lon.get()
});

Upvotes: 7

Views: 4229

Answers (2)

MastaBaba
MastaBaba

Reputation: 1154

To get geolocation to work in Meteor apps compiled as native iOS apps, I needed to add the geolocation package available at https://atmospherejs.com/mdg/geolocation

Upvotes: 1

Christian Fritz
Christian Fritz

Reputation: 21374

As far as I know navigator.geolocation is not a reactive data source. So this won't work without some explicit polling. Another thing that you've got wrong is that your helpers are not functions, so they couldn't be called repeatedly.

This might work (not tested):

Meteor.setInterval(function() {
    navigator.geolocation.getCurrentPosition(function(position) {
        Session.set('lat', position.coords.latitude);
        Session.set('lon', position.coords.longitude);
    });
}, 5000);

Template.location.helpers({
  lat: function() { return Session.get('lat'); },
  lon: function() { return Session.get('lon'); }
});

Upvotes: 4

Related Questions