Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wait for AJAX before continuing through separate function

Alright... at 2am, this is where I draw the line. Help... before my laptop ends up going out the window. :)

I've tried using setTimer, callbacks, and everything else I can think of (along with a few other Stackoverflow hints of course). I've stripped out everything so I'm leaving just the base code.

What I'm looking to do is call parseRow() and before it saves the record at the end, I need to grab the associated Category (via AJAX); however, it blows right past it so category is always "undefined".

function parseRow(row){
    var rowArray     = row.trim().split(",");
    var date         = rowArray[0];
    var checknum     = rowArray[1];
    var payee        = rowArray[2];
    var memo         = rowArray[3];
    var amount       = rowArray[4];

    //ERROR: blows right past this one and sets the category variable BEFORE ajax returns
    var category = autoSelectCategory(payee);

    saveRecord(date, checkNum, payee, memo, category, payment, deposit);
}

function autoSelectCategory(payee) {
    var data;
    $.ajax({
        async: false,
        url: "autoselectcategory",
        dataType: "json",
        data: {
            string: payee
        },
        success: function (returnedData) {
            data = returnedData;
        }
    });
    return data;
}
like image 870
glassfish Avatar asked Jul 02 '12 08:07

glassfish


2 Answers

AJAX stands for asynchronous. That means that in your original code, saveRecord will be executed before the client will receive the response from the server (and, depending on the $.ajax implementation, it might be before the client will send the request to the server).

Additionally, you seem to misunderstand how functions work in JS. var category = autoSelectCategory(payee); will set the category to the return value of autoSelectCategory; but the autoSelectCategory function in your code returns nothing.

From the other side, the data return value of your anonymous function could only be used by $.ajax function (and $.ajax likely ignores the success parameter return value).

Here is the code that should work:

function parseRow(row){
    var rowArray     = row.trim().split(",");
    var date         = rowArray[0];
    var checknum     = rowArray[1];
    var payee        = rowArray[2];
    var memo         = rowArray[3];
    var amount       = rowArray[4];

    autoSelectCategory(payee, function (category) {    
        saveRecord(date, checkNum, payee, memo, category, payment, deposit);
    });
}

function autoSelectCategory(payee, callback) {
    $.ajax({
        async: false,
        url: "autoselectcategory",
        dataType: "json",
        data: {
            string: payee
        },
        success: callback
    });
}
like image 68
penartur Avatar answered Oct 22 '22 02:10

penartur


Do not use async: false option. It's a pure evil (blocks all scripts in browser and even other tabs!) and it's deprecated since jQuery 1.8. You should use callbacks as it was always meant to be.

function parseRow(row) {
    /* the other code */
    autoSelectCategory(payee, function() {
        saveRecord(date, checkNum, payee, memo, category, payment, deposit);
    });
}

function autoSelectCategory(payee, callback) { // <---- note the additional arg
    $.ajax({
        url: "autoselectcategory",
        dataType: "json",
        data: {
            string: payee
        },
        success: function(res) {
            /* the other code */
            callback();
        }
    });
}
like image 32
freakish Avatar answered Oct 22 '22 04:10

freakish