4

I have a form with certain action. When the form is submitted I send an ajax call that calls this action. In the otherhand, I am sending another ajax call to update the progress. I have done it as follows:

    $("form").submit(function() {               
      function callBack()
      {
            if( (this.readyState == 4) && (this.status == 200) )
            {
              console.log(this.responseText);
            }
      }

      function updateProgress (){
        asyncReq('/get_progress?progress='+progress, callBack);
      }

      function asyncReq(url, functionCallBack)
      {
            var request; //request must be a local var to avoid race condition
            try
            {   //for modern browsers
              request = new XMLHttpRequest;
            }
            catch (err)
            {// legacy IE
              request = new ActiveXObject("Microsoft.XMLHTTP");
            }
            request.onreadystatechange = callBack;
            request.open("GET", url, true);
            request.send();
      };
      var progress = $("#progress").val();
      asyncReq('/get_progress?progress='+progress, callBack);
      setTimeout(updateProgress, 2000);
      $(this).ajaxSubmit({async: true});
      return false;
   });

I have 2 asynchronous javascript calls here, one for submitting the form and one for updating the progress. When I print out the responseText in callBack, I can only see 0.0 and 1.0. That is one before the ajaxSubmit() is called and after it is finished. I would like to get all the value of the progress in the middle as well. As far as I understand, the 2nd ajax call for asyncReq is called only after the ajaxSubmit is finished. Can anyone give me any idea about how I make the another complete ajax call before the ajaxSubmit() is complete?

Note:

The form consists of file field and ajaxSubmit unzips, processes the file and updates the progress table after each file is processed. The get_progress method extracts the progress value of that table. I am using jquery.form.js for submitting the form by ajax call.

Sadiksha Gautam
  • 5,032
  • 6
  • 40
  • 71
  • as you're using jQuery, while you are manually creating XMLHttpRequest/ActiveXObject connection? Let jQuery handle this. http://api.jquery.com/category/ajax/ – HungryCoder Oct 24 '12 at 09:26
  • Yeah, I tried to use $.getScript("/get_progress?progress="+progress), but I don't know why but I can only send one ajax request at a time. The 2 ajax requests were not fired simultaneously! – Sadiksha Gautam Oct 24 '12 at 09:33
  • please check the answer i've just posted if it helps you somehow – HungryCoder Oct 24 '12 at 09:49
  • No, this thing is not possible. Because, I can't send 2 requests to a single server. I tried to fire up another server and send one request to another server, but I can't get the response back to the first client from the second server. In rails server, it says 200 completed, but gives me empty response while polling in firebug console. So, I was thinking of sending the task to the background worker and get the response by polling. That, I have yet to try out! :) – Sadiksha Gautam Oct 29 '12 at 10:00
  • why you can't send 2 requests to a single server? – HungryCoder Oct 29 '12 at 10:13

5 Answers5

2

I'm not clear what you've tried to achieve. However, here is simplified version of your codes.

function updateProgress(){
    var progress = $("#progress").val();
    $.get('/get_progress?progress='+progress, function(data){
        //***you will get response in data
        //here you write how to handle progress and data
    }
    setTiemout('updateProgress()', 2000)

}
$('form').submit(function(){
    updateProgress();
    $(this).ajaxSubmit({async: true});
})

I'm not sure what ajaxSubmit() function actually does for you! As name suggests, I guess it just submits the form. Now if you want to put your own logic for showing progress, you just put that logics in *** marked area.

HungryCoder
  • 7,506
  • 1
  • 38
  • 51
  • Yes, this is the simpler version of my code. `ajaxSubmit()` just submits the `form` in the form of ajax request. However, for the first time i get the response from `updateProgress`. But, after the form is submitted through ajax call, i cannot get the complete response from `updateProgress` until the form submission has finished. So, I want to call the `updateProgress` and get the response from it before ajax call of form submission is complete. – Sadiksha Gautam Oct 24 '12 at 10:01
  • did you try the code i've given? please get back after trying it. post error messages, if any – HungryCoder Oct 24 '12 at 10:04
  • yes, your code works but the previous problem that i mentioned still persists! The first ajax call is get_progress, the second one is action of form and the third one is again get_progress. Before the second one is completed, I cannot get the response from the third. I want to get the response of the third ajax call before second ajax call finishes. I hope it is clear now! :) – Sadiksha Gautam Oct 24 '12 at 10:08
  • what you've in` callBack` in your following statement? `asyncReq('/get_progress?progress='+progress, callBack);` – HungryCoder Oct 24 '12 at 10:37
  • I just used your code and it works, except the problem. and the callBack is the first function in my question. It means what to do after the request.readystate has changed. – Sadiksha Gautam Oct 24 '12 at 10:44
  • ok, yes, i forgot about it! your codes actually calls `updateProgress()` once after `2000` ms. It won't call it after each 2000ms. So, i guess, it is not executing after your first call! am I right? – HungryCoder Oct 24 '12 at 11:18
2

You have submitted 3 concurrent ajax requests after two seconds:

  1. asyncReq('/get_progress?progress='+progress, callBack);
  2. setTimeout(updateProgress, 2000); (which runs later)
  3. $(this).ajaxSubmit({async: true});

Are you using an older browser? If so you will run up against the two connection limit. See Max parallel http connections in a browser? and How many concurrent AJAX (XmlHttpRequest) requests are allowed in popular browsers?

If there is a limit on the number of concurrent requests, your timeout request will be queued on the browser and submitted only after the ajax form or first progress is complete.

Community
  • 1
  • 1
pd40
  • 3,187
  • 3
  • 20
  • 29
0

It looks like your code is only updating the progress once after 2000 milliseconds. This line:

setTimeout(updateProgress, 2000);

Have you tried setting an update interval instead? This will make that code run every xxxx milliseconds. Like this:

myVar=setInterval(updateProgress,2000);

Then you need to use clearInterval to stop that code from running. Like this:

clearInterval(myVar);

Notice that I had to add the variable myVar. It is needed for the clearInterval function and will need to be available for it to work. You may have to define it globally as var myVar.

Miguel-F
  • 13,450
  • 6
  • 38
  • 63
  • what do you mean by update interval? I didn't quite understand how it is different from setTimeout! – Sadiksha Gautam Oct 24 '12 at 19:33
  • `setTimeout` will only execute once after the time you specify. Where `setInterval` will run continually every time you specify. So in your example, `setTimeout(updateProgress, 2000)` after 2000 milliseconds it will run updateProgress. That's it, no more. Where as `setInterval(updateProgress, 2000)` after 2000 milliseconds will run updateProgress and it will continue to run updateProgress every 2000 milliseconds until you execute the `clearInterval()` function. – Miguel-F Oct 24 '12 at 19:56
  • @SadikshaGautam this is what i've told you in my last comment and this issue is resolved in my given code. you can just inject your logics in the code template i've posted. – HungryCoder Oct 25 '12 at 04:17
  • But my issue is not with regular updates, that is happening just fine. The problem is that once the ajaxsubmit starts then all the other updates after that are also not completed until this ajaxsubmit is completed. I want somehow this updateProgress to finish in regular intervals while ajaxsubmit is running. – Sadiksha Gautam Oct 25 '12 at 06:43
  • @SadikshaGautam that is exactly what we are trying to get for you and what `setInterval` will provide - running updateProgress in regular intervals. Have you tried the code we are suggesting? @HungryCoder - sorry I did not see your comment about this. It was hidden under the 'click here to see more comments'. – Miguel-F Oct 25 '12 at 12:11
  • yes, I tried setInterval as well but I am getting the same error! :S – Sadiksha Gautam Oct 25 '12 at 23:42
0

Please, check this.

The setTimeout function delays for a specified time period and then triggers execution of a specified function. Once the function is triggered the setTimeout has finished.

The setInterval function also delays for a specified time before triggering the execution of a specific function. Where it differs is that after triggering that function the command doesn't complete. Instead it waits for the specified time again and then triggers the function again and continues to repeat this process of triggering the function at the specified intervals until either the web page is unloaded or the clearInterval function is called.

Aleksei Chernenkov
  • 991
  • 1
  • 8
  • 23
0

Following @HungryCoder's response, you're only missing one thing. You must return false from the form submission.

$('form').submit(function(){
    updateProgress();
    $(this).ajaxSubmit({async: true});
    return false;
});

Without the return false, the form will still do what it does naturally. Alternatively, you could capture the submit event variable.

$('form').submit(function( e ){
    e.preventDefault();
    updateProgress();
    $(this).ajaxSubmit({async: true});
    return false;
});

Calling e.preventDefault() will also prevent the form from doing it's default browser-defined activity (i.e. submitting to the server).

Jarrett Meyer
  • 19,333
  • 6
  • 58
  • 52