Sunday, February 18, 2018

Adding multiple listeners to navigator.geolocation.getCurrentPosition

Leave a Comment

I am adding three listeners for location updates.

<!DOCTYPE html>      <html>      <body>            <p>Click the button to get your coordinates.</p>            <button onclick="getLocation()">Try It</button>            <p id="demo1"></p>      <p id="demo2"></p>      <p id="demo3"></p>            <script>      var x = document.getElementById("demo1");      var y = document.getElementById("demo2");      var z = document.getElementById("demo3");            function getLocation() {          if (navigator.geolocation) {              navigator.geolocation.getCurrentPosition(showPosition1);              navigator.geolocation.getCurrentPosition(showPosition2);              navigator.geolocation.getCurrentPosition(showPosition3);          } else {               x.innerHTML = "Geolocation is not supported by this browser.";          }      }            function showPosition1(position) {          alert("showPosition1");          x.innerHTML = "Latitude: " + position.coords.latitude +  "<br>Longitude: " + position.coords.longitude;      }            function showPosition2(position) {          alert("showPosition2");          y.innerHTML = "Latitude: " + position.coords.latitude + "<br>Longitude: " + position.coords.longitude;      }            function showPosition3(position) {          alert("showPosition3");          z.innerHTML = "Latitude: " + position.coords.latitude + "<br>Longitude: " + position.coords.longitude;      }      </script>            </body>      </html>

In case of Safari and Chrome, all three methods are called. While in case of Firefox, only the last listener method is called.

So what is the default implementation for the location detection feature. Is there a work around to ensure that all the callback methods are called on Firefox.

2 Answers

Answers 1

Firefox had a long history with implementing bugs in geolocation.

What you can do as of now is hack this by monkey patching getCurrentPosition

var getCurrentPosOrg = navigator.geolocation.getCurrentPosition;  function getCurrentPositionMod () {     const listners = [];     function runAllListners(...args) {         listners.forEach(curr => curr(...args));     }     return (cb) => {         listners.push(cb);         getCurrentPosOrg(runAllListners);     } }  navigator.geolocation.getCurrentPosition = getCurrentPositionMod(); 

With this patch, you can simply use getCurrentPosition and do not have to worry about Firefox anymore. If you need to remove listeners you can extend this method to do so as well.

Your snippet will look something like this now.

<!DOCTYPE html>  <html>    <body>      <p>Click the button to get your coordinates.</p>      <button onclick="getLocation()">Try It</button>      <p id="demo1"></p>    <p id="demo2"></p>    <p id="demo3"></p>      <script>      if (navigator.geoloaction) {        var getCurrentPosOrg = navigator.geolocation.getCurrentPosition;          function getCurrentPositionMod() {          const listners = [];            function runAllListners(...args) {            listners.forEach(curr => curr(...args));          }          return (cb) => {            listners.push(cb);            getCurrentPosOrg(runAllListners);          }        }          navigator.geolocation.getCurrentPosition = getCurrentPositionMod();      }      var x = document.getElementById("demo1");      var y = document.getElementById("demo2");      var z = document.getElementById("demo3");        function getLocation() {        if (navigator.geolocation) {          navigator.geolocation.getCurrentPosition(showPosition1);          navigator.geolocation.getCurrentPosition(showPosition2);          navigator.geolocation.getCurrentPosition(showPosition3);        } else {          x.innerHTML = "Geolocation is not supported by this browser.";        }      }        function showPosition1(position) {        alert("showPosition1");        x.innerHTML = "Latitude: " + position.coords.latitude + "<br>Longitude: " + position.coords.longitude;      }        function showPosition2(position) {        alert("showPosition2");        y.innerHTML = "Latitude: " + position.coords.latitude + "<br>Longitude: " + position.coords.longitude;      }        function showPosition3(position) {        alert("showPosition3");        z.innerHTML = "Latitude: " + position.coords.latitude + "<br>Longitude: " + position.coords.longitude;      }    </script>    </body>    </html>

Answers 2

Try it using eventWatcher on geolocation API. This a full HTML and JavaScript.

<!DOCTYPE html> <html>     <head>         <title>DEMO</title>         <meta charset="UTF-8">         <meta name="viewport" content="width=device-width, initial-scale=1.0">     </head>     <body>         <p>Click the button to get your coordinates.</p>          <button onclick="startGeolocation() ">Start Geolocation</button>         <button onclick="stopLocation()">Stop Geolocation</button>          <script>             var observerID = -1;              function startGeolocation() {                 //INITIALIZE EVENT WAHTCER POSITIONS                 if (navigator.geolocation) {                     observerID = navigator.geolocation.watchPosition(onSuccess, onError, {                         maximunAge: 60000,                         enableHighAccuracy: true,                         timeout: 20000                     });                  }              }              function stopGeolocation() {                  if (observerID !== -1) {                     navigator.geolocation.clearWatch(observerID);                     observerID = -1;                  }             }              function onSuccess(pos) {                 //THIS EVENT FIRE WHEN POSITIONS HAVE DATA.                 var lat = pos.coords.latitude;                 var lng = pos.coords.longitude;                 var accuracy = pos.coords.accuracy;                 var altitude = pos.coords.altitude;                 var altitudeAccuraccy = pos.coords.altitudeAccuracy;                 var heading = pos.coords.heading;                 var spped = pos.coords.speed;                 var timeSpan = pos.coords.timestamp;                 //ADD YOU CODE HERE...             }              function onError(error) {                 switch (error.code) {                     case error.PERMISSION_DENIED:                          alert("USER NOT ACCEPTED PERMISSION.");                         break;                     case error.POSITION_UNAVAILABLE:                         alert("POSITION NOT AVAIBLE.");                         break;                     case error.TIMEOUT:                          alert(true, "TIME OUT.");                         break;                     case error.UNKNOWN_ERROR:                         alert(true, "OTHER ERROR.");                         break;                 }              }          </script>     </body>  </html> 
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment