toams7 toams7 - 5 months ago 23
AngularJS Question

Chain 2 HTTP requests and return 2nd promise

Before making an HTTP request, I need to check if the access credentials I have are valid. If they are not valid, I need to make a first HTTP request to revalidate them and, after completion, then a second HTTP request (the original one). The function call needs to return Angular's

$http
promise from the second HTTP request. Here's my function:

var makeRequest = function (scope, address, request, basic, form) {

startLoad(scope);

// Check if user is logged in and needs a new session token...
if (ready() && (now() > getSessionExpires()-20) ) {

// Setup auth.session.refresh request
var refreshRequest = {
"refreshToken": getRefreshToken(),
"clientID": getClientID(),
};

// Make auth.session.refresh request
$http.post(API + 'auth.session.refresh', format(refreshRequest))
.error(function (data) {
// If refresh request fails, logout and redirect to expired message
stopLoad(scope); logoff();
$window.location.href = '/error/expired';
return;
})
.success(function (data) {
// If refresh request succeeds, makeRequest is called recursively and the else condition runs
process(data, true);
return makeRequest(scope, address, request, basic, form);
});

} else { // if not logged in, or if session token is valid, run request function as usual

// Add Authorization header with valid sessionToken
if (ready()) $http.defaults.headers.post['Authorization'] = 'Bearer ' + getSessionToken();

// Basic Request: returns promise (if next context not set, can chain other action)
if (basic) {
return $http.post(API + address, request)
.error(function(data) {

if (data && scope) stopLoad(scope, data.message);
else if (scope) stopLoad(scope, Defaults.serverError);
else stopLoad();

if (form) resetForm(form);
})
.success(function(data) {
process(data);

if (scope) {
stopLoad(scope);
if (scope.context.next) $location.path(scope.context.next);
} else stopLoad();

if (form) resetForm(form);
});
}

// Custom Request: returns promise (can chain .error, .success)
else return $http.post(API + address, request);
}
};


When the token is found to be invalid, however, the function returns undefined, and I get an error that I cannot run .success() or .error(). The else functionality runs, but I'm wondering how I can ensure that I don't get this error. Thank you!

Answer

Just return the upper $http.post(/*...*/) and let promise chaining do it's magic:

    return $http.post(API + 'auth.session.refresh', format(refreshRequest))
                    .catch(function (response) {
                        // If refresh request fails, logout and redirect to expired message
                        stopLoad(scope); logoff();
                        $window.location.href = '/error/expired';
                    })
                    .then(function (response) {
                        // If refresh request succeeds, makeRequest is called recursively and the else condition runs
                        process(response.data, true);
                        return makeRequest(scope, address, request, basic, form);
                    });

UPDATE: since .success/.error functions are not chainable (and have been flagged deprecated), you should use .then and .catch instead.

$http.post(/*...*/)
    .success(function(data) {
        /* do something with data */
    })
    .error(function(err) {
        /*...*/
    });

becomes

$http.post(/*...*/)
    .then(function(response) {
        /*do something with response.data */
    })
    .catch(function(response) {
        /*...*/
    });
Comments