Pepster
Pepster

Reputation: 2166

Nested Service promise not resolved in then()

I got a service which first need to retrieve an accesstoken and then a User object. When this is done, further UI actions needs to be taken. The problem I have is that login().then() is invoked with a valid Session.accesstoken but a non-resolved promise for the Session.user. So I can't do any logic based on the user's info (e.g. role, etc.)

The following code I have:

In controllers.js (login() is invoked upon form credentials button click)

.controller('LoginController', 
function($scope, SessionService) {
    $scope.credentials = {
      username : '',
      password : ''
    };

    $scope.login =
      function() {
        SessionService.login($scope.credentials).then(function() {
          console.info("succesfully logged in as user " + JSON.stringify(Session)); 
          // further UI actions..
        });
      };
   })

In services.js

.factory('SessionService',
  function(User, Session, AuthorizationService) {
    return {
      login : function(credentials) {
        return AuthorizationService.requestToken(credentials)
          .then(function(token) {
            console.info("Got token: " + token);
            if (!!token) {
              Session.create(token);

              console.info("Fetching user...");
              return User.get({
                id : 'me'
              });
            } else {
              throw (new Error("Could not log in"));
            }
          }).then(function(user) {
            console.info("Got user: " + user);
            if (!!user) {
              Session.user = user;
            } else {
              throw (new Error("Could not fetch user"));
            }
          });
      },
    };
  })

Here is the output of the console:

Upvotes: 1

Views: 130

Answers (1)

Nikos Paraskevopoulos
Nikos Paraskevopoulos

Reputation: 40318

The User object is created by $resource and is not a promise; it is the actual object that will eventually be populated with the user info, but at this point of the code it contains nothing.

The solution is simple: from the first then do:

return User.get({...}).$promise;

The next then will be invoked with the user object as expected, but only when the data is actually fetched.

Upvotes: 1

Related Questions