Your code does not work because it is
- Not bound to the digest cycle (and so Angular will not perform dirty checking on it and update the view)
- Is using
setTimeout
, which only queues a one-off task, rather than one that performs at an interval.
Here's an easy adjustment that could be run in a controller:
function onDeviceReady() {
$interval(function() {
navigator.geolocation.getCurrentPosition(onSuccess, onError);
}, 60000)
}
I consider this to be a bad solution in a controller, though. Controllers shouldn't access the DOM (Except component controllers), and yes, navigator
is part of the DOM. Here are two alternatives that use best practices - directives or components.
Angular 1.4
class LocationCtrl {
constructor() {
this.position = null
}
}
function locationContainerDirective($interval) {
function link(scope, el, attrs, ctrl) {
const promise = $interval(() => {
navigator.geolocation.getCurrentPosition(function(position) {
ctrl.onUpdatePosition({ position })
})
}, 60000)
scope.$on('$destroy', () => $interval.cancel(promise))
}
return {
scope: {
onUpdatePosition: '&'
},
bindToController: true,
restrict: 'E',
require: 'location',
controller: LocationCtrl,
controllerAs: 'location',
transclude: true,
template: '<div ng-transclude></div>',
link
}
}
Angular 1.5 (or 1.3 with a shim)
I'd propose creating a container component that provides a position via a callback, like so:
angular.component('position', {
outputs: {
onUpdatePosition: '&'
}
controller: class PositionCtrl {
constructor($interval) {
this.$interval = $interval
}
$onInit() {
this.$interval(() => {
navigator.geolocation.getCurrentPosition((position) => {
this.onUpdatePosition({ position })
})
})
}
}
})
This could then be used like so in a component:
<position on-update-position='$ctrl.onUpdatePosition(position)'></position>
<google-map focus='$ctrl.position'></google-map>
Where <google-map>
is some arbitrary component that uses a navigator position.