ShaneKm
ShaneKm

Reputation: 21328

jQuery call ajax every second until call finishes / returns true

I need to be able to call a function getProgress every second. This function does an ajax request and updates a progress bar. I need to be able to stop the call to this function when a call returned from ajax is "true".

Html:

<td class="checkbox">
<input type="checkbox" value="6" class="checkbox download" id="chk-6">
<div class="hide" id="prgbar-6"><span class="progresslabel"></span></div>
</td>

My function:

function getProgress(operationId) { // receives operationId
    $.post("@Url.Action("Status","Packages")", { operationId: operationId }, function (data) {
        if (data) {
            for (var key in data) {
                if ($("#prgbar-" + key + "").size() != 0) {
                    var objPrg = $("#prgbar-" + key + "");
                    var objchk = $("#chk-" + key + "");
                    if (data[key]) {
                        objPrg.find("span").text("downloading...").css("color:#000000");
                        objchk.hide();
                        objPrg.removeClass("hide").show().progressbar({
                            value: 0
                        });
                        var value = Math.floor(parseInt(data[key]) * 100);
                        objPrg.progressbar("option", "value", value);
                        objPrg.find("span").text(value + "%");
                    } else {

                    }
                }
            }
        }
    });
}

Upvotes: 0

Views: 1159

Answers (3)

Vinay
Vinay

Reputation: 6322

I like this method. It requires no clearing of intervals. It just runs on its own and sets a timeout if necessary.

var operationId = ...;
var processFunction = function () {
        $.post("@Url.Action("Status","Packages")", { operationId: operationId }, function (data) {
            if (data !== true) {
                // your normal function stuff
                setTimeout(processFunction, 1000);
            }
        });
    };

setTimeout(processFunction, 1000);

Upvotes: 1

A. Wolff
A. Wolff

Reputation: 74420

var interval = setInterval(function(){getProgress(operationId,interval)},1000);

In your $.POST complete callback function, clear this interval: {i use complete here but if you want to do only for successful request, use .success()}

$.post("@Url.Action("Status","Packages")", { operationId: operationId }, function (data) {
        if (data) {
            for (var key in data) {
                if ($("#prgbar-" + key + "").size() != 0) {
                    var objPrg = $("#prgbar-" + key + "");
                    var objchk = $("#chk-" + key + "");
                    if (data[key]) {
                        objPrg.find("span").text("downloading...").css("color:#000000");
                        objchk.hide();
                        objPrg.removeClass("hide").show().progressbar({
                            value: 0
                        });
                        var value = Math.floor(parseInt(data[key]) * 100);
                        objPrg.progressbar("option", "value", value);
                        objPrg.find("span").text(value + "%");
                    } else {

                    }
                }
            }
        }
    }).complete(function() { clearInterval(interval); });

Upvotes: 1

That White Eyebrow Guy
That White Eyebrow Guy

Reputation: 569

Method #1:

You could just make a variable outside of the function called requestRunning and on calling getProgress it checks if requestRunning is true.

// Pseudo-code
var requestRunning = false;
if requestRunning === true  => continue with getProgress
if requestRunning === false => stop firing getProgress

Method #2:

Use setInterval and on success of the request and clear the interval.

var progressHandle = setInterval(function(){getProgress(id)}, 1000);

$.ajax({
  success: function() {
    clearInterval(progressHandle);
  }
});

I'd probably prefer the first option although progress checking through subsequent AJAX calls isn't really good.

Upvotes: 0

Related Questions