2

I didn't understand the behavior of the return value of then ,

Here its documentation -

then(successCallback, errorCallback, notifyCallback) – 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.

So let's try it , according to the follow little code section -

var deferred = $q.defer();
deferred.reject();
deferred.promise.then(function () {
        console.log("1st resolove");
    },
    function () {
        console.log("1st reject");
    }
).then(function () {
    console.log("2nd resolve");
    },
    function () {
        console.log("2nd reject");
    }
);

1) Why does it log -

1st reject
2nd resolve

instead of -

1st reject
2nd reject

?

2) What do I have to change to make it log -

1st reject
2nd reject

?

var myAppModule = angular.module('myApp', []).
  controller('myCtrl',function($scope,$q){
   var deferred = $q.defer();
   //deferred.resolve();
   deferred.reject();
   deferred.promise.then(function () {
     console.log("1st resolove");
    },
    function () {
     console.log("1st reject");
    }
   ).then(function () {
    console.log("2nd resolve");
    },
    function () {
     console.log("2nd reject");
    }
   );
  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.20/angular.min.js"></script>
<div ng-app="myApp">
  <div ng-controller="myCtrl"></div>
 </div> 
URL87
  • 10,667
  • 35
  • 107
  • 174
  • 1
    Adding to RGraham: If you want the 2nd promise to get rejected too, return `$q.reject()`. The reason for this initially odd behaviour is that your 1st rejection function may be able to correct the error and continue normally with the chained promise. Also another note: if you *omit* the 1st rejection handler, then the second promise is auto-rejected. – Nikos Paraskevopoulos Jun 24 '15 at 07:49
  • see also: [Promise's second .then() not failing](http://stackoverflow.com/q/23943322/1048572) – Bergi Jun 24 '15 at 08:10

1 Answers1

7

You missed the next line of the docs:

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

If you want the next chain to be the result of the same promise for whatever reason, return deferred.promise from inside your handler.

// This will always trigger the reject callback
deferred.promise.then(function () {
        console.log("1st resolove");
        return deferred.promise;
    },
    function () {
        console.log("1st reject");
        return deferred.promise;
    }
)

If you want to return either the success/failed callback, depending on the result of the first, return $q.when() inside your success and return $q.reject() inside your failure:

deferred.promise.then(function () {
        console.log("1st resolove");
        return $q.when();
    },
    function () {
        console.log("1st reject");
        return $q.reject();
    }
).then(function () {
        console.log("2nd resolve");
    },
    function () {
        console.log("2nd reject");
    }
);

Example

CodingIntrigue
  • 75,930
  • 30
  • 170
  • 176