user1881482 user1881482 - 6 months ago 10
Javascript Question

How to wait for AJAX calls in an each loop to complete before moving on without ASYNC: FALSE

I currently have setup a AJAX to PHP set of functions that processes a number of items on a page. Basically the code inserts a series of tasks into the database, then inserts supplies into the database based on those newly created task ID's. However it works 90% of the time. Sometimes it seems as though the Task ID's are not created first which doesn't allow the supplies to use those ID's for inserting into the database. Is there a way to make sure that the task is inserted, then all supplies are inserted for that ID, then move onto the next one. At the end when all is complete I would like to redirect to a new page, again I put this in the last success call on the supplies portion, but it would redirect on the first loop. This process usually generates around 5 tasks, with 12 supplies per each task. I was reading about a

$.when
loop but could not get it to work.

$(document).on("click", "#submitTasks", function(e) {
e.preventDefault();
var tasks = $('#tasks').find('.box');
var project_id = $('#project_id').val();
tasks.each(function() {
var trs = $(this).find('.reqTables').find('.table').find('tbody').find('tr');
var task_definition_id = $(this).find('.task_definition_id').val();
var labor_type_id = $(this).find('.laborAmount').children('option:selected').val();
var task_status_id = 1;
var qty_labor = $(this).find('.laborQty').val();
var amount_labor = $(this).find('.laborTotal').val();
var amount_materials = $(this).find('.matTotal').val();
var amount_gst = $(this).find('.gstTotal').val();
amount_materials = +amount_materials + +amount_gst;
amount_materials = amount_materials.toFixed(2);
var active = 1;
//console.log(div)
var task = {
project_id : project_id,
task_definition_id : task_definition_id,
labor_type_id : labor_type_id,
task_status_id : task_status_id,
qty_labor : qty_labor,
amount_labor : amount_labor,
amount_materials : amount_materials,
active : active
};
saveTasks(task, trs, project_id);
});
});
function saveTasks(task, trs, project_id) {
$.ajax({
type : "POST",
url : "<?php echo base_url(); ?>" + "mgmt/project/saveTasks",
data : task,
dataType : "json",
cache : "false",
success : function(data) {
trs.each(function() {
var total = $(this).find('input[name="calculatedCost"]').val();
if (total != 'n/a') {
var task_id = data;
var supply_id = $(this).find('.suppliesPicker').children('option:selected').val();
var task_requirement_id = $(this).find('td:first-child').data('id');
var qty = $(this).find('input[name="calculatedQty"]').val();
var cost_per = $(this).find('.costPicker').val();
var delivery_cost = $(this).find('input[name="transport"]').val();

var notes = '';
var qty_actual = '';
var active = 1;
var taskSupply = {
task_id : task_id,
supply_id : supply_id,
task_requirement_id : task_requirement_id,
qty : qty,
cost_per : cost_per,
delivery_cost : delivery_cost,
total : total,
notes : notes,
qty_actual : qty_actual,
active : active
};
saveTaskSupplies(taskSupply);
console.log(taskSupply);
}
});
}
});
}

function saveTaskSupplies(taskSupply) {
$.ajax({
type : "POST",
url : "<?php echo base_url(); ?>" + "mgmt/project/saveTaskSupplies",
data : taskSupply,
dataType : "json",
cache : "false",
success : function(data) {
***** I WANT TO REDIRECT TO A NEW PAGE WHEN THE LAST ONE OF THESE COMPLETES ******
}
});
}

Answer

Here is a direct solution using the code you provided. The basic concept is to increment a counter as supplies are processed. Once the counter reaches the total number of supplies, a procedure is run. See comments throughout.

var totalTaskSupplies = 0;
var processedTaskSupplies = 0;

$(document).on("click", "#submitTasks", function(e) {
    e.preventDefault();
    var tasks = $('#tasks').find('.box');
    var project_id = $('#project_id').val();

    tasks.each(function() {
        var trs = $(this).find('.reqTables').find('.table').find('tbody').find('tr');
        var task_definition_id = $(this).find('.task_definition_id').val();
        var labor_type_id = $(this).find('.laborAmount').children('option:selected').val();
        var task_status_id = 1;
        var qty_labor = $(this).find('.laborQty').val();
        var amount_labor = $(this).find('.laborTotal').val();
        var amount_materials = $(this).find('.matTotal').val();
        var amount_gst = $(this).find('.gstTotal').val();

        // Add number of supplies for current task to total task supplies
        totalTaskSupplies += trs.length;

        amount_materials = +amount_materials + +amount_gst;
        amount_materials = amount_materials.toFixed(2);
        var active = 1;
        //console.log(div)
        var task = {
            project_id : project_id,
            task_definition_id : task_definition_id,
            labor_type_id : labor_type_id,
            task_status_id : task_status_id,
            qty_labor : qty_labor,
            amount_labor : amount_labor,
            amount_materials : amount_materials,
            active : active
        };
        saveTasks(task, trs, project_id);
    });
});
function saveTasks(task, trs, project_id) {
    $.ajax({
        type : "POST",
        url : "<?php echo base_url(); ?>" + "mgmt/project/saveTasks",
        data : task,
        dataType : "json",
        cache : "false",
        success : function(data) {
            trs.each(function() {
                var total = $(this).find('input[name="calculatedCost"]').val();
                if (total != 'n/a') {
                    var task_id = data;
                    var supply_id = $(this).find('.suppliesPicker').children('option:selected').val();
                    var task_requirement_id = $(this).find('td:first-child').data('id');
                    var qty = $(this).find('input[name="calculatedQty"]').val();
                    var cost_per = $(this).find('.costPicker').val();
                    var delivery_cost = $(this).find('input[name="transport"]').val();

                    var notes = '';
                    var qty_actual = '';
                    var active = 1;
                    var taskSupply = {
                        task_id : task_id,
                        supply_id : supply_id,
                        task_requirement_id : task_requirement_id,
                        qty : qty,
                        cost_per : cost_per,
                        delivery_cost : delivery_cost,
                        total : total,
                        notes : notes,
                        qty_actual : qty_actual,
                        active : active
                    };
                    saveTaskSupplies(taskSupply);
                    console.log(taskSupply);
                }
            });
        }
    });
}

function saveTaskSupplies(taskSupply) {
    $.ajax({
        type : "POST",
        url : "<?php echo base_url(); ?>" + "mgmt/project/saveTaskSupplies",
        data : taskSupply,
        dataType : "json",
        cache : "false",
        success : function(data) {
            ++processedTaskSupplies;

            // All supplies have been processed
            if (processedTaskSupplies == totalTaskSupplies) {
                // Do something
            }
        }
    });
}
Comments