0

I'm seeing some odd behavior with the Firebase Simple Login when used with Angular.

I'm not able to get $scope variables to bind as expected. I would think that or $scope.test would change after successful login, but it doesn't. It stays false even after login. Given that this is my first Angular project, I'm guessing it's something simple, but I've looked all over and haven't found an answer.

The code is quite simple. First the HTML:

<body ng-app>
    <div ng-controller="LoginController">
        <div ng-hide="test">
            <h1>Welcome.  Please log in.</h1>
            <p>Test is {{test}}</p>
            <label>Username</label>
            <input type="text" ng-model="username" />
            <label>Password</label>
            <input type="password" ng-model="password" />
            <button ng-click="login()">Log in</button>
        </div>
        <button ng-show="test" ng-click="logout()">Log out</button>
    </div>

    <script type='text/javascript' src='https://cdn.firebase.com/js/client/1.0.6/firebase.js'></script>
    <script type='text/javascript' src='https://cdn.firebase.com/js/simple-login/1.2.5/firebase-simple-login.js'></script>
    <script type="text/javascript" src="js/lib/angular.js"></script>
    <script type="text/javascript" src="js/controllers/LoginController.js"></script>
</body>

And the one controller:

function LoginController($scope) {
    var FB = new Firebase("https://[myfirebase].firebaseio.com");
    $scope.user = false;
    $scope.error = false;
    $scope.test = false;

    $scope.auth = new FirebaseSimpleLogin(FB, function(error, user){
        if(error) {
            $scope.error = error;
        } else if(user) {
            // would expected binding to take effect here, but not
            $scope.user = user;
            $scope.test = true;
        } else {
            console.log("no user");
        }
    });

    $scope.logout = function() {
        this.auth.logout();
    };

    $scope.login = function () {
        console.log("Attempting login");
        this.auth.login('password', {
            email: this.username,
            password: this.password
        });
    };
}

Thanks to anyone who can point me in the right direction.

2
  • Is your login actually being called? It seems like you might have an issue with using this rather than $scope for 'auth' in your login method. Commented Mar 8, 2014 at 4:14
  • It doesn't appear that you're using AngularFire, which helps bridge the gap between Angular and Firebase. They even have a seed project (ala angular-seed) with working login controller that does 3-way data binding! You should check it out. github.com/firebase/angularFire-seed github.com/firebase/angularFire Commented Mar 15, 2014 at 2:58

1 Answer 1

3

You need to use $scope.$apply() to let angular know you've changed something on the scope. You need to do this when integrating 3rd party libraries with watched scope variables.

$scope.auth = new FirebaseSimpleLogin(FB, function(error, user){
    $scope.$apply(function() {
        if(error) {
            $scope.error = error;
        } else if(user) {
            // would expected binding to take effect here, but not
            $scope.user = user;
            $scope.test = true;
        } else {
            console.log("no user");
        }
    }
});
Sign up to request clarification or add additional context in comments.

2 Comments

Clearly a newb mistake. That works just as expected. Thanks Phil.
I find that $timeout is a bit safer than $scope.$apply. Particularly with Firebase, where the methods sometimes return synchronously (i.e. might be inside an apply scope already, which causes an error)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.