Naxon
Naxon

Reputation: 1414

Too much recursion on ajax request

Here is the code of my register.js page:

$(document).on('pagecreate', '#register', function() {
    $('#submit').click(function() {
        $('.frmFields').removeClass('error');
        var errors = 0;

        var fields = {
            username: $('#username'),
            name: $('#name'),
            email: $('#email'),
            password: $('#password'),
            vPassword: $('#password_verify'),
            dob: $('#dob')
        };

        $.each(fields, function(key, value) {
            if (value.val() == '') {
                value.addClass('error');
                errors++;

                alert('שדה ' + key + ' הינו שדה חובה');
            }

            if (key == 'name') {
                if (!isText(value.val())) {
                    value.addClass('error');
                    errors++;

                    alert('שדה שם חייב להכיל טקסט בלבד');
                }
            }

            if (key == 'email') {
                if (!isEmailAddress(value.val())) {
                    value.addClass('error');
                    errors++;

                    alert('שדה דואר אלקטרוני חייב להכיל כתובת תקנית');
                }
            }
        });

        if (fields.password.val() != fields.vPassword.val()) {
            vPassword.addClass('error');
            errors++;

            alert('הסיסמאות שהקלדת אינן זהות');
        }

        function checkUsername(uname) {
            var valid = false;

            $.ajax({
                url: './actions/checkUsername.php',
                type: 'GET',
                async: false,
                data: {
                    username: fields.username.val()
                },
                success: function(resp) {
                    if (resp == "success")
                        $('#valid').val('true');
                    else
                        $('#valid').val('false');
                }
            });
        }

        checkUsername(fields.username.val());

        if ($('#valid').val() == 'true') {
            $.ajax({
                url: './actions/register.php',
                type: 'POST',
                data: fields,
                success: function(resp) {
                    if (resp == "success") {
                        alert('yay!');
                    } else
                        alert(resp);
                }
            });
        } else
            alert('שם המשתמש שבחרת תפוס');
    });
});

Everything is working fine, the data is being sent correctly, only that I get an error:

too much reccursion

It happens because of the last $.ajax call. I tried it with $.post and it does the same.

How can I do this correctly so I won't get this error?

Upvotes: 0

Views: 1662

Answers (2)

Alon Eitan
Alon Eitan

Reputation: 12025

This is what I would do:

$(document).one('pagecreate', '#register', function() {
    $('#submit').click(function() {
        $('.frmFields').removeClass('error');
        var errors = 0;

        // BUG HERE - Take a look at @Musa's answer
        var fields = {
            username: $('#username'),
            name: $('#name'),
            email: $('#email'),
            password: $('#password'),
            vPassword: $('#password_verify'),
            dob: $('#dob')
        };

        $.each(fields, function(key, value) {
            if (value.val() == '') {
                value.addClass('error');
                errors++;

                alert('שדה ' + key + ' הינו שדה חובה');
            }

            if (key == 'name') {
                if (!isText(value.val())) {
                    value.addClass('error');
                    errors++;

                    alert('שדה שם חייב להכיל טקסט בלבד');
                }
            }

            if (key == 'email') {
                if (!isEmailAddress(value.val())) {
                    value.addClass('error');
                    errors++;

                    alert('שדה דואר אלקטרוני חייב להכיל כתובת תקנית');
                }
            }
        });

        if (fields.password.val() != fields.vPassword.val()) {
            vPassword.addClass('error');
            errors++;

            alert('הסיסמאות שהקלדת אינן זהות');
        }

        function registerUsername() {
            if ($('#valid').val() == 'true') {
                $.ajax({
                    url: './actions/register.php',
                    type: 'POST',
                    data: fields,
                    success: function(resp) {
                        if (resp == "success") {
                            alert('yay!');
                        } else
                            alert(resp);
                    }
                });
            } else
                alert('שם המשתמש שבחרת תפוס');
            }
        }

        $.ajax({
            url: './actions/checkUsername.php',
            type: 'GET',
            async: false,
            data: {
                username: fields.username.val()
            },
            success: function(resp) {
                if (resp == "success")
                    $('#valid').val('true');
                else
                    $('#valid').val('false');
                registerUsername();
            }
        });       
    });
});
  • I have changed $(document).on('pagecreate', '#register', function() { TO $(document).one('pagecreate', '#register', function() { in order to prevent multiple click bindings on the #submit button
  • Made the register login called after you check the username validity

Please note that you can put the registerUsername function outside the click event, making it available to other functions within the same scope the 'registerUsername' function is.

EDIT:

A different approach is to delegate the click event to the element:

$(document).on('click', '#register #submit', function() {
    -- PUT HERE THE SUBMIT LOGIC --
});

This way you don't need to use the pagecreate event, because you're binding the click event to the button, even when it still doesn't exist inside the DOM (Thanks @charlietfl - Now I understand what you meant in the comments below).

Please note that eventually @Musa's answer is the correct one. But i'll leave my answer here too because of the event delegation suggestion and that fact that you're calling register.php before the checkUsername.php call is complete (My answer shows a possible alternative)

Upvotes: 0

Musa
Musa

Reputation: 97682

The problem is you are passing jQuery objects in the data part of your ajax call. Instead have the values.

    var data = {
        username: $('#username').val(),
        name: $('#name').val(),
        email: $('#email').val(),
        password: $('#password').val(),
        vPassword: $('#password_verify').val(),
        dob: $('#dob').val()
    };
        $.ajax({
            url: './actions/register.php',
            type: 'POST',
            data: data,
            success: function(resp) {
                if (resp == "success") {
                    alert('yay!');
                } else
                    alert(resp);
            }
        });

Upvotes: 3

Related Questions