title: AngularJS: geolocation + promise + $apply
body: <p>I have some problems using the geolocation AngularJS plugin <a href="https://github.com/arunisrael/angularjs-geolocation/blob/master/src/geolocation.js" rel="nofollow">https://github.com/arunisrael/angularjs-geolocation/blob/master/src/geolocation.js</a>.</p>
  
  <p>When you look at line 17, an <code>$apply</code> is called. This seems ok for me, because the callback of the <code>getCurrentPosition</code> runs async, and out of the scope of angular's digest:</p>
  
  <pre><code>angular.module('geolocation')
    .factory('geolocation', ['$q','$rootScope','$window','geolocation_msgs','$timeout',function ($q,$rootScope,$window,geolocation_msgs,$timeout) {
      return {
        getLocation: function (opts) {
          var deferred = $q.defer();
          if ($window.navigator &amp;&amp; $window.navigator.geolocation) {
            $window.navigator.geolocation.getCurrentPosition(function(position){
              $rootScope.$apply(function(){deferred.resolve(position);});
            }
  </code></pre>
  
  <p>In a normal desktop browser this works fine. But when used inside a PhoneGap app, along with cordovas geolocation plugin (<a href="https://github.com/apache/cordova-plugin-geolocation" rel="nofollow">https://github.com/apache/cordova-plugin-geolocation</a>), it throws an <code>$digest already in progress</code> error on iOS7.</p>
  
  <p>So, I did a little bit of debugging, and found out, that the following version works everywhere, on a desktop browser AND inside a PhoneGap app:</p>
  
  <pre><code>angular.module('geolocation')
    .factory('geolocation', ['$q','$rootScope','$window','geolocation_msgs','$timeout',function ($q,$rootScope,$window,geolocation_msgs,$timeout) {
      return {
        getLocation: function (opts) {
          var deferred = $q.defer();
          if ($window.navigator &amp;&amp; $window.navigator.geolocation) {
            $window.navigator.geolocation.getCurrentPosition(function(position){
              deferred.resolve(position);
            }
  </code></pre>
  
  <p>So, I'm a little bit confused.</p>
  
  <ol>
  <li>Is the whole callback still in angular's scope?</li>
  <li>If so, why does an <code>$apply</code> call don't throw an <code>$digest already in progress</code> error on my desktop browser?</li>
  <li>And if it's not in the scope, why does just a <code>deferred.resolve(position);</code> work? Does this have anything to do with references to the <code>deferred</code> var?</li>
  <li>Do I have to wrap the <code>resolve</code> call on a promise (and outside of angulars digest scope) inside an <code>$apply</code> callback?</li>
  </ol>
  
  <p>Hope someone can help me to clear my mind!</p>