简体   繁体   中英

Why am I not getting proper response/error in AngularJS factory using .then()?

I have a factory in Angular, where I want to add an alert if an error is encountered.

Here's my call to the factory:

gradeService.assignGrade(requestData).then(Controller.populateResponseObject, Controller.error);

where Controller just a this for the current controller: var Controller = this .

When I try to trigger the error in the UI, a 500 Server Error is encountered(as expected), but it goes to populateResponseObject , not to error . How to I get the service to return error?

Here's the service code:

app.factory('gradeService', function ($http) {

    var baseUrl = "http://localhost:8080";

    var add = function (request) {
        var requestUrl = baseUrl + "/grade/new";

        return $http.post(requestUrl, request)
        .then(function (responseSuccess) {
            return responseSuccess.data;
        },
        function (responseError) {
            return responseError.data;
        });
    };

    return {
        assignGrade: add
    };
});

Here's the relevant error code:

Controller.error = function (error) {
    // ... some code
    else if(error.status === 500) {
        if(error.exception === "org.springframework.dao.DataIntegrityViolationException") alert("Error: this person has already been graded for this month. Grade was not saved.");
        else if(error.exception === "java.sql.SQLException") alert("Error establishing connection with database. Please try again later.");
        else alert("Error: " + error.message + ": Generic Server Error.");
    }
};

I'm using Spring for the backend code.

Any help?

Your problem is that you do not return a promise in your assignGrade()/add() function but the response data. That means that there will be no correct promise handling made by Angular.

Just do the following, then your handling should work fine:

 app.factory('gradeService', function ($http) { var baseUrl = "http://localhost:8080"; var add = function (request) { var requestUrl = baseUrl + "/grade/new"; return $http.post(requestUrl, request); }; return { assignGrade: add }; }); 

To chain an error, throw it back to the onRejected function.

app.factory('gradeService', function ($http) {

    var baseUrl = "http://localhost:8080";

    var add = function (request) {
        var requestUrl = baseUrl + "/grade/new";

        return $http.post(requestUrl, request)
        .then(function onFulfilled(responseSuccess) {
            return responseSuccess.data;
        },
        function onRejected (responseError) {
            //to chain rejection throw it
            throw responseError;
            //Not return
            //return responseError.data;
        });
    };

    return {
        assignGrade: add
    };
});

Returning something from an onRejected handler converts the derived promise to a fulfilled promise.

For more information, see Angular execution order with $q .

You have to handle promise in controller not in service.

app.factory('GradeService', function ($http) {
    var obj = {}
    var baseUrl = "http://localhost:8080";

    obj.add = function (request) {
        var requestUrl = baseUrl + "/grade/new";

        return $http.post(requestUrl, request);
    };

    return obj;
});

I think the above code will give solve your issue.

First, modify the factory:

app.factory('gradeService', function ($http) {

    var baseUrl = "http://localhost:8080";

    var add = function (request) {
        var requestUrl = baseUrl + "/grade/new";

         return $http.post(requestUrl, request);
    };

    return {
        assignGrade: add
    };
});

Then, call the factory like this:

gradeService.assignGrade(requestData).then(function(success) {
    // Some success code...
}, function(error) {
    // Some error code...
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM