I thought that I had this all figured out on previous projects through the years.. Apparently not.
Goal : Take Service that calls other Services and if there is any
it seems that the promise returned by SparkRequestService.submitRequest(request)
is not rejected when you get the error inside resData
. For this reason the successCallback of then
is invoked and not the second one, the errorCallback.
For this reason, inside the successCallback you need to inspect the data of resData
to check errors and behave accordingly, for example:
var getSubmit = function (request) {
return SparkRequestService
.submitRequest(request)
.then(function (resData) {
console.log("resData", resData);
if(resData === null) { // Check for errors
// There is an error, manage it inside this block of code
// ...
// You can also create a rejected promise with $q.reject() and passing resData containing the errors
return $q.reject(resData);
} else {
// Call resetEnrollment() in the ELSE branch so, it is executed only if resData does not contain errors
enrollmentService.resetEnrollment();
return resData;
}
},
function (resData) {
console.log('error');
}
);
};
To prevent a rejection handler from converting a rejected promise to a fulfilled promise it is important use a throw
statement in the rejection handler:
var getSubmit = function (request) {
return SparkRequestService
.submitRequest(request)
.then(
function (resData) {
console.log("resData", resData);
enrollmentService.resetEnrollment();
return resData;
},
function (errorResponse) {
console.log('error');
//IMPORTANT
//throw to chain rejection
throw errorResponse;
}
);
}
When a function omits a return
or throw
statement, the function returns a value of undefined
. This will convert a rejected promise to a fulfilled promise that resolves with a value of undefined
.
Problem is that ... it is a business error wrapped up in a return object
To convert a fulfilled promise to a rejected promise, use a throw
statement.
this.submitEnrollment = function (enrollment) {
var promise = getSubmit(requestData);
var newPromise = promise.then(function(response) {
if (response.data.hasErrors) {
console.log(response.data.errorList);
response.data.errorList.push("submitEnrollent: Rejected");
//THROW to create rejection
throw response;
} else {
//RETURN response to chain success
return response;
}
});
return newPromise;
}
When a promise is converted to a rejection, all subsequent success handlers in the chain will be skipped. The chain will be followed until a rejection handler is found.