Angular Promises and Chaining: How to break a chain if it has business data errors

旧城冷巷雨未停 提交于 2019-12-01 11:55:15

问题


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 type of error being returned ( not a status of 200 ) then I need the async thing to be waiting and not proceeding.

Seems to me like I don't ever see really that great of examples as it is all very simplistic.

I read various articles about what Angular (1) is doing under the hood , and i see that there are $q, .then, .success etc..

Seems that I am having issues with return and with other nested and bundled service calls being made without any checking of a problem.

Essentially this image shows what is coming back

data : null ( that is bad) errorList Array1 0 "This order cannot be submitted... " ( bad too) hasErrors : true ( bad as well)

So that data is important to me to capture and display to user and then NOT move onto more processing

This is my order of operations

this.submitEnrollment = function (enrollment) {
    return getSubmit(requestData);
}

// Which CALLS below

var getSubmit = function (request) {
    return SparkRequestService
        .submitRequest(request)
        .then(
            function (resData) {
                console.log("resData", resData);
                enrollmentService.resetEnrollment();
                return resData;
            }, 
            function (resData) {
                console.log('error');
            }
        );
}

Then I'm certainly calling SparkRequestService.submitRequest(request) but based on the image attached, I am getting the error in the resData

So, it seems that I need to interrogate the resData right? So then I really should NOT ALLOW this other service to be called enrollmentService.resetEnrollment();

How can i refactor to stop from that getting processed? if statement in the .then ?


回答1:


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.




回答2:


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');
            }
        );
};


来源:https://stackoverflow.com/questions/42362821/angular-promises-and-chaining-how-to-break-a-chain-if-it-has-business-data-erro

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!