简体   繁体   中英

Angular promise (of a promise?). Or how do I chain a .then after an $http.success in angular

I got a service in Angular:

App.factory('AuthService', function ($q, $http, CredentialStorage) {
  var _endpoint = 'http://localhost:3000';
  return {
    login: function (credentials) {
      return $http
        .post('/api/users/login', credentials)
        .success(function (apiResult) {
          var deferred = $q.defer();

          if (apiResult.code == 0) { 
            $scope.user = apiResult.context;
            CredentialStorage.store(apiResult.context);
          }

          return deferred.promise;
        })
        .fail(function(apiResult, status, headers) {
          var deferred = $q.defer();
          return deferred.promise;
        });
    },
....});

Where I authenticate and store the user in some cookie or whatever (this is not relevant).

Then on my controller I got:

App.controller('LoginController', function ($scope, $rootScope, AuthService) {
    var _login = function($event) {
        $event.preventDefault();

        AuthService.login($scope.l).then(function() {
            alert('aaa');
            if (!AuthService.authenticatedUser) {
                $scope.errors = ['Invalid username and password. Please try again.'];
                alert($scope.errors);
            } else {
                alert('a' + $scope.errors);
            }
        })
    }
    $scope.login = _login;
});

For some reason my controller's then doesnt execute. Why is that?

Thanks

Well, the simple answer is: you use .then which chains instead of success which just adds a listener:

App.factory('AuthService', function ($q, $http, CredentialStorage) {
  var _endpoint = 'http://localhost:3000';
  return {
    login: function (credentials) {
      return $http
        .post('/api/users/login', credentials)
        .then(function (response) {
          var apiResult = response.data;
          if (apiResult.code == 0) { 
              CredentialStorage.store(apiResult.context);
              return apiResult.context; // promises let you return the value
          }
          throw new Error("Authentication failed"); // return $q.reject
                                                    // if you don't want to invoke
                                                    // exceptionHandler
        });
    },
....});

Which would let you do:

   AuthService.login($scope.l).then(function(result) {
        $scope.user = result;
   }).catch(function(err){
        // code to handle the case authorization failed or the API call failed
   });

From Angular separation of concern's stand point, it is generally bad to modify UI scopes in a service/factory/provider. It's better to return the results.

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