0

i have the following validate script to run before the form is submitted:

    function validateMyForm(){
    var numberTo = $('.to').length

    $('.to').each(function(){
        var product_id = $(this).closest('tr').find('input').get(0).id;
        var todate = $(this).val();
        var from = $(this).prev().prev().val();
        $.ajax({
            type: 'POST',
            url: myBaseUrl + 'Products/ajax_change_date',
            dataType: 'json',
            data: {
                id: product_id,
                todate: todate,
                from: from

            },
            success: function (data) {
                numberTo--;
            }
        });
    });

    while(numberTo != 0){

    }
    return true;
}

However when i run this i get a message box in firefox saying its waiting for the script to complete.

How do i avoid that while still keeping the ajax?

Marc Rasmussen
  • 19,771
  • 79
  • 203
  • 364
  • 1
    You can't wait for an asynchronous operation to finish. Javascript is single-threaded, so while your main thread is in the loop, it never executes the callback. – Barmar Feb 01 '14 at 14:29
  • Depending on how many $('.to') are in your page, you may end up with many Ajax requests, which may significantly slow down your app. You might want to group together some of the requests to save performance. – BogdanBiv Feb 01 '14 at 14:35

2 Answers2

3

Using:

while(numberTo != 0){

}

You create infinity loop and your scrip stop executing. This is why you get this error on Firefox.

You will need to have callback to check numberTo variable.

For example:

function validateMyForm(){
    var numberTo = $('.to').length;

    function checkNumberTo() {
        if( numberTo ===  0 ) {
            alert( 'AJAX Completed' );
            // here you should include your code to manually submit the form
        }
    }

    $('.to').each(function(){
        var product_id = $(this).closest('tr').find('input').get(0).id;
        var todate = $(this).val();
        var from = $(this).prev().prev().val();
        $.ajax({
            type: 'POST',
            url: myBaseUrl + 'Products/ajax_change_date',
            dataType: 'json',
            data: {
                id: product_id,
                todate: todate,
                from: from

            },
            success: function (data) {
                numberTo--;
                checkNumberTo()
            }
        });
    });
    return false;
}
antyrat
  • 27,479
  • 9
  • 75
  • 76
1

If you want a more elegant solution you might want to try a promise library. Here is an essay https://gist.github.com/domenic/3889970 that presents the downside of using callbacks and the solution to it - Promises. The essay is long, but it is worthy to read.

To get to how this new concept applies to you, you should try researching Promise composition, here is the first article I could find on Google on this: http://strongloop.com/strongblog/how-to-compose-node-js-promises-with-q/.

var x = 10; var promise1 = Q($.ajax(...)).then(function () { x = 20; }); var promise2 = Q($.ajax(...)) .then(function () { x = 30; });

var groupPromise = Q.all([ promise1(), promise2() ]) groupPromise.then(function (results) { }, console.error) // Kris Kowal's example

Promises l and 2 execute in paralel and one does not know which will be fulfilled first. Here are 2 relevant promise libraries:

BogdanBiv
  • 1,485
  • 1
  • 16
  • 33