Pregunta

So I have recently started using AngularFire since it renders the use of a backend completely useless.

I am trying to see in a registerform if the email already exists. At the moment there is one emailaddress 'xxx' in the firebase, however I am not capable of adding a second entry since I keep getting an undefined function. To clarify, here is the code in my controller:

 $scope.submitForm = function (isValid) {
        if (isValid) {
            var resolved = checkEmail($scope.add.email);
            console.log('resolved = ' + resolved);
            if (resolved) {
                console.log('I should be here');
                $scope.addEntry();
            } else if (!resolved) {
                console.log('Am I seriously getting in here ???');
            }
        } else {
            alert('failed!')
        }
    };

var db = new Firebase("https://radiant-fire-1289.firebaseio.com/");

function checkEmail(inputEmail) {
    db.on('child_added', function (snapshot) {
        var data = snapshot.val();
        if (data.email.toUpperCase() === inputEmail.toUpperCase()) {
            return false;
        } else {
            console.log('I am in checkEmail');
            return true;
        }
    })
}

inputEmail is obviously the email I put in my html form. The function correctly returns true when submitting email address 'bbb' , it is not equal to 'xxx'. the submitForm function gets called from the form when pressing on the submit button. isValid is just some validation of the form, this works correctly. However the boolean 'resolved' is always undefined. I have a feeling this has something to do with asynchronous functions, however since I am a newbie at javascript (and especially firebase) I have trouble understanding what it is exactly what I am doing wrong.

The console does log 'I am in checkEmail' before he logs 'resolved = ' + resolved, but resolved keeps printing as undefined instead of true. Then the console prints 'Am I seriously getting here ???' which leads to no entry being added. (I guess undefined is the same as false for the compiler? )

¿Fue útil?

Solución

The on function is asynchronous. This means that the callback is not executed until after a remote call to Firebase completes. The checkEmail function has already run before the result is fetched, so there is no return value. You could test this by adding a console.log right before the end of checkEmail, which you would note runs before your "I'm in checkEmail" log.

Additionally, there is a misunderstanding of scope here. Return false/true inside of the db.on callback is not somehow propagated up to checkEmail, so the result of checkEmail would always be undefined, even if this were a synchronous call.

To do this correctly, you want to invoke another callback when the result is fetched:

$scope.submitForm = function (isValid) {
        if (isValid) {
            var resolved = checkEmail($scope.add.email, function(resolved) {
               console.log('resolved = ' + resolved);
               if (resolved) {
                 console.log('I should be here');
                 $scope.addEntry();
               } else if (!resolved) {
                 console.log('Am I seriously getting in here ???');
               }
            });
        } else {
            alert('failed!')
        }
    };

var db = new Firebase(URL);

function checkEmail(inputEmail, callback) {
    db.on('child_added', function (snapshot) {
        var data = snapshot.val();
        if (data.email.toUpperCase() === inputEmail.toUpperCase()) {
            callback(false);
        } else {
            console.log('I am in checkEmail');
            callback(true);
        }
    })
}

Last but not least, you'll want to learn about Angular's HTML compiler and $q. The child_added event is not going to be fired inside Angular's compile scope (since it's asynchronous) so you'll need to manually trigger a compile using $timeout if you make any changes to $scope.

See the Firebase + Angular Getting Started Guide, which will introduce you to the correct way to integrate, and provides a lib called angularFire that handles all these complexities on your behalf.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top