0

Trying to do a while loop using $.getJSON to return progress of a certain task. The initial $.getJSON works flawlessly; however the loop never completes. I am passing certain variables through a backend php file which is the reason for the variables in the script.

$.getJSON('http://anyorigin.com/get?url=https://".$domain.".instructure.com/api/v1/courses/".$course_id."/course_copy/".$id."?access_token=".$token."&callback=?', function(data){
    var progress = data.contents.progress;
    alert(progress);
    var elem = document.getElementById('".$id."');
    elem.style.width = progress + '%';
});

var progress_check = 0;
//The part below doesn't work! //
do {
    $.getJSON('http://anyorigin.com/get?url=https://".$domain.".instructure.com/api/v1/courses/".$course_id."/course_copy/".$id."?access_token=".$token."&callback=?', function(data){
        var progress_check = data.contents.progress;
        alert(progress_check);
        var elem = document.getElementById('".$id."');
        elem.style.width = progress_check + '%';
    });
} 
while (progress_check < 100);

I want the script to update a specific div with a new css style to display the loading bar properly. Here is the div:

<div id='".$id."-div' class='progress progress-striped active'>
   <div id=".$id." class='bar' style='width: 1%'></div>
</div>

Not certain what i am doing wrong. Thanks in advance.

7
  • 1
    Indenting your code consistently and clearly will help you dramatically when reading your code. And make it a lot easier for people trying to help you to read it, too. Due respect, that code is extremely hard to read. (I was trying to clean it up for you, but jsbeautifier.org seems to be down...) Commented May 16, 2013 at 17:32
  • I don't even see an infinite loop in your code. You're trying to do something in a loop that you should be doing with setTimeout anyway - JS is asynchronous, not multithreaded. Also, I'll add the jquery tag on your post, not all Javascript is jQuery and you should specify it. Commented May 16, 2013 at 17:34
  • That's a horrible way of testing the progress. It may fire off thousands of ajax requests before the complete one happens, if the browser doesn't stop you before that. And it ruins the asynchronous nature of ajax. You also are not updating the variable on the outside of the ajax (which is why your loop is infinite) Commented May 16, 2013 at 17:38
  • possible duplicate of How to return the response from an AJAX call? Commented May 16, 2013 at 17:39
  • @meagar not really a duplicate - the devil is in the detail and a good solution for this won't necessarily require the same answer as to that question. Commented May 16, 2013 at 17:55

3 Answers 3

3

your var progress_check = data.contents.progress; is local variable it becomes zero each time function completes. change it to progress_check = data.contents.progress; and check.

Sign up to request clarification or add additional context in comments.

Comments

1

The $.getJSON call is asynchronous - the result isn't known until the AJAX call completes. Furthermore, because the function returns immediately it'll fire as many AJAX calls in parallel as it possibly can. On top of that, your progress variable is being overwritten inside the callback function, so the variable of the same name in the while condition is never updated.

Try this, instead:

function poll(url) {

    var def = $.Deferred();

    (function loop() {
        $.getJSON(url).done(function(data) {
            var progress = data.contents.progress;
            if (progress < 100) {
                def.notify(progress);
                loop();
            } else {
                def.resolve();
            }
        }).fail(def.reject);
    )();

    return def.promise();
}

which abstracts your polling into a function that returns a "promise".

You can then watch for progress events on that promise, and watch for completion of the loop:

poll(myUrl).progress(function(percent) {
    var elem = document.getElementById(...);
    elem.style.width = percent + '%';
}).done(function() {
    // this is called when the loop is finished
}).fail(function() {
    // this is called if any of the AJAX calls break the loop
});

and now your progress display logic is completely separated from the AJAX code, with the only hard-coded dependency in the poll function being which JSON property to look in to find the current progress value.

Comments

0

use javascript timer to make ajax request, make progress track request in every 30seconds/60 seconds
This will be better than do while loop

1 Comment

As mentioned in several of the OP comments, the setTimeout was the best way to handle this. after changing it and cleaning it up, it was quite simple.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.