Jofran
Jofran

Reputation: 79

Successive AJAX calls add an extra consecutive call

I have a pretty standard ajax call for a live update, however, say I call the the ajax, everything is good, but say I want to call it again, this time, I will get 2 calls, and if I try again then I'll have 3, I can verify this by invoking and alert and with the Network DevCon of Chrome, any idea why this is happening?

P.S: I'm using Laravel 5.1

$('button[name=act]').click(function() {
    var icon = $(this).closest('div.thumbnail').find('i');

    $(document).ajaxStart(function() {
        icon.show();
    });

    $("form").submit(function (e) {

        e.preventDefault();

        var formData = new FormData($(this)[0]);

        $.ajax({
            url: "ajax/acttdb",
            data: formData,
            dataType: "json",
            type: "POST",
            cache: false,
            contentType: false,
            processData: false,
            success: function (data, status, jqXhr) {
                $(icon).fadeIn(function() {
                    $(this).removeClass('fa-spinner fa-spin').addClass('fa-check text-success').fadeOut(1000, function() {
                        $(this).removeClass('fa-check text-success').addClass('fa-spinner fa-spin');
                    });
                });
            }/*,
               error: function (jqXhr, textStatus, errorThrown) {
               console.log("Error response:", jqXhr.responseText);
               }*/
        });
    });
});

Upvotes: 1

Views: 115

Answers (3)

techdude
techdude

Reputation: 1334

The reason this is happening is because you are rebinding the submit event function every time the button is clicked which results in multiple copies of the function. Just move it out of the click even, and if you want to force a submit on a click, you can call the submit() function with no parameters to fire the event.

Try the following:

$(function(){
    $('button[name=act]').click(function(){
        var icon = $(this).closest('div.thumbnail').find('i');

        $(document).ajaxStart(function()
        {
            icon.show();
        });

        $("form").submit(); //This submits the form on click
    });

    //This binds the function, so it should only be called once.
    $("form").submit(function (e)
    {
        e.preventDefault();

        var formData = new FormData($(this)[0]);

        $.ajax({
            url: "ajax/acttdb",
            data: formData,
            dataType: "json",
            type: "POST",
            cache: false,
            contentType: false,
            processData: false,
            success: function (data, status, jqXhr)
            {
                //BLAH
            }
        });
    });
});

I noticed two other things you might want to address. You want to somehow update the icon after it is loaded. You will need to have some other way to find the icon inside of the success function (possibly looking at the data that came back could yield some information that could be useful. Since it is json, it should be easy to update.)

Also, the way you currently have it will bind to all forms on the page. In the event that you have multiple forms on the page, you will probably want to change the selector to use an id.

Hope this helps!

Upvotes: 1

Barmar
Barmar

Reputation: 781583

The problem is that every time you click on the act button you call $("form").submit(), which adds anothersubmithandler to the form. So if you click on theact` button 3 times, and then click on the form's submit button, it will send 3 AJAX requests.

It's almost always wrong to bind one event handler inside another event handler, you should bind all the event handlers at top level.

var icon;

$(document).ajaxStart(function() {
    if (icon) {
        icon.show();
    }
});

$('button[name=act]').click(function() {
    icon = $(this).closest('div.thumbnail').find('i');
});

$("form").submit(function (e) {
    e.preventDefault();
    var formData = new FormData($(this)[0]);
    $.ajax({
        url: "ajax/acttdb",
        data: formData,
        dataType: "json",
        type: "POST",
        cache: false,
        contentType: false,
        processData: false,
        success: function (data, status, jqXhr) {
            if (icon) {
                icon.fadeIn(function() {
                    $(this).removeClass('fa-spinner fa-spin').addClass('fa-check text-success').fadeOut(1000, function() {
                        $(this).removeClass('fa-check text-success').addClass('fa-spinner fa-spin');
                    });
                });
            }
        }/*,
           error: function (jqXhr, textStatus, errorThrown) {
           console.log("Error response:", jqXhr.responseText);
           }*/
    });
});

Upvotes: 2

Joaquín O
Joaquín O

Reputation: 1451

Based in incremental calls and my guessings, I have to say that you're printing this code each time you make the (ajax) call, leading to bind your form element again in each call.. Am I right?

JO.

Upvotes: 0

Related Questions