4
votes

I have the following controller that uses AngularFire

app.controller("authController", function($scope, $firebaseSimpleLogin){

var ref = new Firebase("https://myapp.firebaseIO.com/");
$scope.auth = $firebaseSimpleLogin(ref, function(error, user){
    if(error){
        console.log(error);
    }
    else if(user){
        console.log(user);
    }
    else{
        console.log("user logged out");
    }
});

// This shows a valid object
console.log($scope.auth);

$scope.createAccount = function(){
    console.log("found me");
    $scope.auth.$createUser($scope.email, $scope.password, function(error, user){
        console.log("something");
        console.log(user);
        if(!error){
            console.log(user);
        }
        else{
            console.log(error);
        }
    });
};

});

When I bind the $scope.createAccount function to an ng-click event and click on the bound button, console.log("found me") runs in the browser, but none of the other console.log commands in $scope.createAccount is shown.

The console.log($scope.auth) command I have before setting the $scope.createAccount function shows a valid object with the $createUser function defined.

I am not receiving any console errors when I run $scope.createAccount so I am assuming the call has been "successfully" made.

Why am I able to see the auth object, but not receiving a callback after calling $createUser?

1

1 Answers

12
votes

This was happening because I was doing callbacks based on JavaScript notation instead of Angular notation. Since I was using the AngularFire methods (they have the same names as the vanilla JavaScript SDK methods, but with a $ sign in front of them), I needed to handle callbacks using Angular's $promise methodology.

I changed

$scope.auth.$createUser($scope.email, $scope.password, function(error, user){
    // do things;
});

to

$scope.auth.$createUser($scope.email, $scope.password)
    .then(function(user){
        // do things if success
    }, function(error){
        // do things if failure
    }); 

and the callback worked as expected.

There is an exception to the above with the vanilla JS firebaseSimpleLogin constructor vs Angular $firebaseSimpleLogin constructor. On the vanilla JS constructor, there are callbacks on the constructor that allows you to specify what your script should do when a user logs in / logs out. It follows the following format:

var auth = new firebaseSimpleLogin(ref, function(error, user){
    if(error){
        // do things if login failure
    }
    else if(user){
        // do things when login succeeds 
    }
    else{
        // do things when user logs out
    }
});

If you try to do the same with the Angular constructor like so:

$scope.auth = $firebaseSimpleLogin(ref)
    .then(function(user){
        // do things when login succeeds 
    }, function(error){
        // do things when login fails     
    });

you'll receive an error. There are no callback methods with the Angular constructor. I am guessing this was done on purpose since with Angular, you have data binding and you can simply $watch $scope.auth.user for changes and perform operations in your app depending on the variable's state. When $scope.auth.user is set to null, the user is logged out. If the value is set to anything else than null, then the user is logged in.