0

I have a little abstraction I wrote around $http that I use to make calls from a security service. The problem I am having is that during a request that results in a 401, the deferred does not seem to propogate correctly.

I am using it like so, and even if it is a 401 it alerts good... I would expect this to alert bad.

security.login('test', 'password').then(function (r) {
            alert('good');
        }, function (r) {
            alert('bad');
        });

Http Wrapper

angular.module('app').provider('http', function () {
    return {
        $get: ['$http', 'url', function ($http, url) {
            function http(config) {
                config.headers = {
                    'X-Requested-With': 'XMLHttpRequest'
                };
                config.url = url.formatUrl(config.url);
                return $http(config);
            }

            return {
                delete: function (url, data) {
                    return http({ url: url, data: data, method: 'DELETE' });
                },
                get: function (url) {
                    return http({ url: url, method: 'GET' });
                },
                post: function (url, data) {
                    return http({ url: url, data: data, method: 'POST' });
                },
                put: function (url, data) {
                    return http({ url: url, data: data, method: 'PUT' });
                }
            };
        }]
    };
});

Security Service

function User() {
    this.displayName = '';
    this.permissions = [];
}

angular.module('app').provider('security', function () {
    var _user = new User();

    return {
        $get: ['$rootScope', '$q', 'cookie', 'http', 'statePermissions', function ($rootScope, $q, cookie, http, statePermissions) {
            function login(params) {
                return http.post('SS/auth', params).then(function (response) {
                    cookie.set('authToken', response.data.authToken);
                    _user = response.data;

                    $rootScope.$broadcast('event:loginSuccessful', _user);

                    return response;

                }, function (response) {
                    cookie.expireNow('authToken');
                    _user = new User();

                    $rootScope.$broadcast('event:loginUnsuccessful', _user);

                    $q.reject(response);

                });
            }

            return {
                doesAuthTokenExist: function () {
                    return angular.isDefined(cookie.get('authToken'));
                },
                getUser: function () {
                    return _user;
                },
                isUserAuthorizedForPermission: function (permission) {
                    var x;

                    for (x = 0; x < _user.permissions.length; x++) {
                        if (_user.permissions[x] === permission) {
                            return true;
                        }
                    }

                    return false;
                },
                isUserAuthorizedForState: function (stateName) {
                    if (angular.isDefined(statePermissions[stateName])) {
                        return this.isUserAuthorizedForPermission(statePermissions[stateName]);
                    }

                    return true;
                },
                login: function (userName, password) {
                    return login({ username: userName, password: password });
                },
                loginWithAuthToken: function () {
                    var authToken = cookie.get('authToken');

                    return login({ provider: 'token', authToken: authToken });
                },
                logout: function () {
                    return http.post('SS/auth/logout').then(function () {
                        cookie.expireNow('authToken');
                        _user = new User();

                        $rootScope.$broadcast('event:logoutSuccessful', _user);

                        return true;
                    });
                }
            };
        }]
    };
});
2
  • What is a status of the response? Try console.log(r.status) instead of alert (regardless of callback type) and paste here result please Commented Jan 2, 2014 at 23:04
  • btw, I found discussion about handling 401 response, it should help you: stackoverflow.com/questions/11971213/… Commented Jan 2, 2014 at 23:07

1 Answer 1

1

Your $http wrapper looks like it's duplicating the functionality of angular's $resource service. Check out the documentation here: http://docs.angularjs.org/api/ngResource.$resource

After a brief look at your code, it seems like the problem could be with how you're using $q. Try rewriting your login method along these lines.

With insight from here:
http://docs.angularjs.org/api/ng.$q
http://docs.angularjs.org/api/ng.$http

function login(params) {

            var deferred = $q.defer();

            http.post('SS/auth', params).success(function (response) {
                cookie.set('authToken', response.data.authToken);
                _user = response.data;

                $rootScope.$broadcast('event:loginSuccessful', _user);

                deferred.resolve(response);

            }).error(function (error) {
                cookie.expireNow('authToken');
                _user = new User();

                $rootScope.$broadcast('event:loginUnsuccessful', _user);

                deferred.reject(error);

            });

            return deferred.promise;
        }

Also, just curious why you are using providers here as it's not obvious to me?

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

1 Comment

I realized I was returning the .then() instead of the promise from the login() method... I use providers for all my services, I was under the understanding that all services, factories, etc are providers under the sheets anyways... In this instance I need to configure some settings that are yet to be implemented.

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.