2

Hi in the following Angular controller i try to initiate facebook login with Parse.com. So I created a promise triggered on fbLogIn. What it is supposed to do, is first login to facebook, and grab first_name and store it in fieldValuesService.ff. THEN, it is supposed to access this value and do something with it. For illustration purpose I just used console logs. What happens is that the second console.log in second then is triggered before the first one from first .then thus is undefined. I don't understand why anything in the second .then can be triggered before first one in this situation.

Also second problem, after a logout, the fbLogIn function is sometime inactive: it won't trigger the login process again.

If you have a clue on this issue your help will be greatly appreciated.

.controller('logController',
    function ($scope, $q, fieldValuesService) {
        var defer = $q.defer();

         defer.promise
         .then(function() {
                 Parse.FacebookUtils.logIn(null, {
                     success: function(user) {
                         if (!user.existed()) {
                             alert("User signed up and logged in through Facebook!");
                         } else {
                             $scope.currentUser = user;
                             $scope.$apply();
                             FB.api('/me', function(response) {
                                 fieldValuesService.ff = response.first_name;
                                 console.log(fieldValuesService.ff); //logs bob

                             });
                         }
                     },
                     error: function(user, error) {
                         alert("User cancelled the Facebook login or did not fully authorize.");
                     }
                 });
             })
         .then(function(){
                 console.log(fieldValuesService.ff); //logs undefined
         });


        $scope.fbLogIn = function() {
               defer.resolve();

           };

         // Parse log out
        $scope.logOut = function(form) {
            Parse.User.logOut();
            $scope.currentUser = null;

        };
    });   
Robert Brax
  • 6,508
  • 12
  • 40
  • 69
  • I'm thinking your problem may be that your first `then` does not return a promise for the second `then` to execute on. – Joachim Isaksson Dec 27 '13 at 18:50
  • I bet that `FB.api` is asynchronous, which means that that `function(response)` gets called **after** the second `then` handler. – a better oliver Dec 27 '13 at 20:00
  • I added the FB.api in its own then handler: .then(function(){ FB.api('/me', function(response) { return response; }) ; then access it in next then handler but still got same issue – Robert Brax Dec 27 '13 at 21:15

1 Answers1

3

Maybe if you restructure your code, things will become a little bit easier.

I recommend to refactor everything FB related into its own service like:

module.factory('FBService', function ($q) {
    var login,
    logout,
    getInformation;
    login = function () {
        var defered = $q.defer();
        Parse.FacebookUtils.logIn(null, {
            success: function (user) {
                defered.resolve(user);
            },
            error: function (user, error) {
                defered.reject(user, error);
            }
        });
        return defered.promise;
    };
    logout = function () {
        var defered = $q.defer();
        Parse.User.logOut();
        defered.resolve();
        return defered.promise;
    };
    getInformation = function () {
        var defered = $q.defer();
        FB.api('/me', function (response) {
            defered.resolve(response);
        });
        return defered.promise;
    }
    return {
        login: login,
        logout: logout,
        getInformation: getInformation
    };
});

module.controller("LoginCtrl", function ($scope, FBService, fieldValuesService) {
    $scope.fbLogIn = function () {
        FBService.login().then(function (user) {
            $scope.currentUser = user;
            return FBService.getInformation();
        }).then(function (information) {
            fieldValuesService.ff = information.first_name;
            console.log(fieldValuesService.ff);
        });
    };
    $scope.logOut = function () {
        FBService.logout().then(function () {
            $scope.currentUser = null;
         });
    };
});
kfis
  • 4,739
  • 22
  • 19
  • Thanks for great answer. It works as intended. These post that help solve real problem in different direction are always enlightening. If I add more .then handlers that pass values to next .then handlers, that don't need factory processing, will they be deferred, or must I necessarily pass by the factory / defer / promise ? – Robert Brax Dec 28 '13 at 11:08