0

I have an service in my Angular app that is responsible for authorizing the user and returning the auth token back.

However, due to the async nature of $http, I cannot properly isolate the logic of my service. Instead I must return a promise and push the logic of interpreting the response to the caller of the service (single responsibility red flag).

Given this, it's made me reconsider whether I am thinking about this correctly. I come from a Java world where the majority of interactions are synchronous, so something isn't sitting well with me as I try to architect a clean design with single responsibility.

What am I missing here?

UPDATE I realize the below will not work as intended, but that's my thought of how I'd like it to work at least:

app.service('AuthenticationService', ['$http', '$httpParamSerializerJQLike', function($http, $httpParamSerializerJQLike)
{
    this.authServerBaseURL = "...";
    this.clientId = "...";

    this.authenticate = function(username, password)
    {
        var config =
        {
            headers:
            {
                "Content-Type"  : 'application/x-www-form-urlencoded',
                "Authorization" : "Basic " + btoa(this.clientId + ":")
            }
        }

        var body = $httpParamSerializerJQLike(
        {
            grant_type : "password",
            username : username,
            password : password
        });

        return $http.post(this.authServerBaseURL + '/oauth/token', body, config).
            success(function(data, status, headers, config)
            {               
                return data.access_token;
            }).
            error(function(data, status, headers, config)
            {
                return false;
            });    
    }

}]);
2

1 Answer 1

2

Update after you added code: Your thought process can work, see below. However, $http docs say not to use .success and .error. If you instead use .then, as in my examples below, it will work.

Assuming your code is something similar to this:

// AuthService
this.authenticate = function() {
    return $http.post('http://example.com', body, config);
}

// Using it:
AuthService.authenticate().then(function(data) {
    var token = data.access_token;
});

You can move the knowledge about how the data is extracted to the service like this:

// AuthService
this.authenticate = function() {
    return $http.post('http://example.com', body, config).then(function(data) {
        return data.access_token;
    });
}

// Using it:
AuthService.authenticate().then(function(token) {
    var token = token;
});

what happens here is that you make a new promise by calling .then on the $http promise, which is what is returned. The promises are chained, so the $http promise will resolve this new promise, which then resolves itself with the extracted token.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for explaining the situation - that worked great for me!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.