AngularJS Geolocation Digest Test
This test shows that the callback from window.navigator.geolocation.getCurrentPosition() doesn't trigger a digest when $scope is updated.
HTML
<div ng-app>
<div ng-controller="GeoTestCtrl">
<div ng-hide="supportsGeo">
Your browser doesn't support geolocation
</div>
<div ng-show="supportsGeo">
Manual digest when position received: <input type="checkbox" ng-model="manualDigest"/>
<br/>
<button ng-click="doTest1()">
Geo Location Test 1: window.navigator.geolocation
</button>
<button ng-click="doTest2()">
Geo Location Test 2: $window.navigator.geolocation
</button>
<hr/>
Need to type something to trigger digest:
<input type="text" ng-model="something"/>
<hr/>
Position: <button ng-click="position=null">clear</button>
<pre ng-bind="position|json"/>
</div>
</div>
</div>
<hr/>
<div>
<p>
This test shows that using the <code>geolocation.getCurrentPosition()</code> callback withing AngularJS prevents message digest from occuring when the $scope is updated inside the callback.
</p>
<p>
I encountered this originally when I abstracted the geolocation into a <code>service</code> that returned a promise so it could do further work on the result before returning. This means that the service needs a <code>$rootScope</code> dependancy to manually trigger the <code>$digest</code>. Since <code>$scope</scope> isn't available to the service unless it is passed in as an argument to the factory instance, <code>$rootScope</code> ensures this isn't forgotten.
</p>
</div>
CSS
p { padding: .5em 0; }
JavaScript
function GeoTestCtrl($scope, $window) {
$scope.supportsGeo = $window.navigator;
$scope.position = null;
$scope.doTest1 = function() {
window.navigator.geolocation.getCurrentPosition(function(position) {
$scope.$apply(function() {
$scope.position = position;
});
}, function(error) {
alert(error);
});
};
$scope.doTest2 = function() {
$window.navigator.geolocation.getCurrentPosition(function(position) {
$scope.$apply(function() {
$scope.position = position;
});
}, function(error) {
alert(error);
});
};
}