0

I have this code:

var geocode = function(value) {
 var request;
 .....
 var dResult = Q.defer();
 geocoder.geocode(request, function (results) {
   dResult.resolve(results);
 });
 return dResult.promise;
};

var cancelWatch;
$scope.$watch('value', function (value) {
 $timeout.cancel(update);
 update = $timeout(function () {
   $scope.geocodedResult = geocode(value);
 }, 300);
});

in line 15 $scope.geocodedResult is a promise that sooner or later will become the result value and the scope should refresh. This unfortunately does not happen. The code works if I do

geocode(value).then(function(result) {
 $scope.geocodedResult = result;
 $scope.$digest();
});

What am I doing wrong?

UPDATE:

I'm now trying to use only $q but I cannot get it to work:

this.getCurrentPosition = function () {
    var dCurrentPosition = $q.defer();
    if (currentPosition) {
        dCurrentPosition.resolve(currentPosition);
    } else {
        navigator.geolocation.getCurrentPosition(function (cp) {
            currentPosition = cp;
            dCurrentPosition.resolve(currentPosition);
        });
    }
    return dCurrentPosition.promise;
};
this.getCurrentLoc = function () {
    return self.getCurrentPosition().then(function (currentPosition) {
        return [currentPosition.coords.longitude, currentPosition.coords.latitude];
    });
};

a breakpoint in

return [currentPosition.coords.longitude, currentPosition.coords.latitude];

will never get triggered while it works fine with Q

nicco82
  • 179
  • 2
  • 9
  • 1
    Please add all relevant code to the question. Stay out from external links when unnecessary. – Stewie Jul 03 '13 at 07:10
  • In the working version you are doing nothing wrong. In the non-working version, you assign the promise as if it were a result, but promises don't work like that - they don't magically metamorphose into the result they promise to deliver. In order to work with the result when it arrives, a promise's `.then()` method needs to be invoked, with a suitable callback. – Beetroot-Beetroot Jul 03 '13 at 11:50

1 Answers1

0

If you use Angular's $q instead of Q, it should work:

var dResult = $q.defer();

$q promises are recognized by the templating engine in angular, which means that in templates you can treat promises attached to a scope as if they were the resulting values. -- $q docs

So $scope.geocodedResult can be set to the $q promise, and when the promise is resolved, the scope property will automatically update.

Mark Rajcok
  • 362,217
  • 114
  • 495
  • 492
  • Thanks, tried to migrate to $q but cannot make it to work (see the updated question) – nicco82 Jul 03 '13 at 20:28
  • @nicco82, depending on how getCurrentLoc() is called, you may need to call $apply(), because the results of resolve() are propagated asynchronously. See http://stackoverflow.com/a/14762098/215945 for more info. – Mark Rajcok Jul 03 '13 at 21:34