0

I am currently learning how to use Angular.js and was attempting to write my own authentication code using a REST-like API. Below is the code for my authentication service.

The problem with my signIn function is that it always returns false, even when my api returns HTTP 200. After some time, I figured out that it is because of the synchronous nature of javascript that the return response; statement is executed before the response = res.data.key; statement.

I don't know how to execute the return statement after the assignment is complete (if the response is HTTP 200). How do I do this?

angular.module('app').factory('auth', ['Base64', '$http', function(Base64, $http) {
    return {
        signIn: function(email, password) {
            var response = false;
            var encoded = Base64.encode(email + ':' + password);
            $http.defaults.headers.common.Authorization = 'Basic ' + encoded;
            $http.post('api/v1/sign_in', {}).then(function(res) {
                if (res.status == 200) {
                    response = res.data.key;
                }
            });
            return response;
        }    
    }
}]);

2 Answers2

2

You need to learn about promises: return the promise from the http post.

This may help

Nathan
  • 6,095
  • 2
  • 35
  • 61
2

Use $q.defer():

angular.module('app').factory('auth', ['Base64', '$http', '$q', function(Base64, $http, '$q') {
    return {
        signIn: function(email, password) {
            var response = false;
            // You create a deferred object
            // that will return a promise
            // when you get the response, you either :
            // - resolve the promise with result
            // - reject the promise with an error
            var def = $q.defer();
            var encoded = Base64.encode(email + ':' + password);
            $http.defaults.headers.common.Authorization = 'Basic ' + encoded;
            $http.post('api/v1/sign_in', {}).then(function(res) {
                if (res.status == 200) {
                    response = res.data.key;
                    // success: we resolve the promise
                    def.resolve(response);
                } else {
                  // failure: we reject the promise
                  def.reject(res.status);
                }
            });
            // You return the promise object that will wait 
            // until the promise is resolved
            return def.promise;
        }    
    }
}]);

Now, you can do:

auth.signIn().then(function(key) {
    // signin successful
    // do something with key
}).catch(function(err) {
    // signin failed :(
    // do something with err
}).finally(function() {
    // you could do something in case of failure and success
})
cl3m
  • 2,791
  • 19
  • 21