5

I have my application that should open a popup ask a confirmation at the user, then make an ajax cal and close the popup.
I tried to do it using a chain of promise (I've already used it, and I remember that it should work in this way), but it seems to block after the call toreservationService.confirm($scope.object);. Now it is a fake service implemented with a setTimeout and $q just to return a promise (in future it will make the ajax call). Is this a valid code or I didn't undestood how promise works?
For the popup I choose AngularUI and the code is this:

 reservationService.book($scope.object, day)
        .then(function(){
            var dialogOpts = {/* dialog options omitted*/}
            return $dialog.dialog(dialogOpts).open();

        })
        .then(function(result){
            console.log('confirmed? ', result);
            if (result){
                //After this line it doesn't do nothing, also if the promise is resolved 
                return reservationService.confirm($scope.object);
            }
        })
        .then(function(){
            //this function is never executed
            $scope.$emit('object:detail',{object: $scope.object});
        });

reservationService:

function confirm(){
     var deferred = $q.defer();
     setTimeout(function(){
          console.log('Confirming');
          deferred.resolve(true)
     }, 500);
     return deferred.promise;
}

SOLVED change setTimeout with $timeout angular's service

rascio
  • 8,968
  • 19
  • 68
  • 108

2 Answers2

6

Used $timeout instead of setTimeout 'cause it works togheter at the angular scope, forcing the digest phase (or use $scope.apply() inside the setTimeout).

rascio
  • 8,968
  • 19
  • 68
  • 108
2

Can you try

//skipping the first then
.then(function(result){
            var deferred = $q.defer();
            console.log('confirmed? ', result);
            if (result){
                //After this line it doesn't do nothing, also if the promise is resolved 
                return deferred.resolve(reservationService.confirm($scope.object));
            }
            deferred.resolve();
            return deferred.promise;
        })
.then(function(){
                //this function is never executed
                $scope.$emit('object:detail',{object: $scope.object});
            });

For chaining then, the last then success or failure function should return a promise. As the $q documentation mentions

then(successCallback, errorCallback) – regardless of when the promise was or will be resolved or rejected, then calls one of the success or error callbacks asynchronously as soon as the result is available. The callbacks are called with a single argument: the result or rejection reason.

This method returns a new promise which is resolved or rejected via the return value of the successCallback or errorCallback.

Chandermani
  • 42,589
  • 12
  • 85
  • 88
  • In this way it works, but it is at the same way the `reservationService` works... – rascio Aug 28 '13 at 10:38
  • I don't get what you mean to say? – Chandermani Aug 28 '13 at 10:40
  • I was editing the post...look now there is the implementation of the `confirm` method. It is implemented at the same way you did...but why I have to call the `deferred.resolve` passing in it the `promise` returned from the service, when it is resolve from the `setTimeout`? – rascio Aug 28 '13 at 10:41
  • `reservationService` returns a promise so you can call `then` on it. This `then` again returns a promise that is resolved by `return $dialog.dialog(dialogOpts).open();` (internally i think) hence the next chained `then` gets called. The second `then` **does** return promise but there is no call to resolve it, and hence the next then never gets executed. – Chandermani Aug 28 '13 at 10:46
  • ahah no..the problem was something with the `setTimeout` that doesn't call some phase of angular, in fact, now I changed the `setTimeout` with `$timeout` and it works correctly, with my code. Promise `then` method should return a `promise` and doesn't have to `resolve` it. – rascio Aug 28 '13 at 10:49