2

I have a page which fires Ajax requests for validations at server side. I need to perform an action when all the ajax requests have finished loading or are completed.

For this, I am using Ext.Ajax.isLoading() in a recursive function in following way:

function chechValid(){
    if(Ext.Ajax.isLoading()){
        checkValid();
    }else{
        //Code for Action 1
    }
}//EOF

checkValid();

//Code for Action 2

The problem is that when I do this, browsers give the following errors:

Mozill FF - too much recursions

IE - Stack overflow at line:18134

If this recursion is a heavy thing for the browsers, then how to perform a task when all the Ajax requests have finished loading?

Using delay is not what I want as, if delay is used then browser begins executing the other code (like 'Code for Action 2' as shared above) which is not what is expected.

The main aim is that the browser shouldn't execute anything unless all the Ajax requests are complete and once completed then it should perform a particular action.

Any suggestions/help on this one?

Thanks in Advance.

PS: Using ExtJs 4.0.7

(Updated)More Detail about the actual situation:-

Here is brief description of the situtaion being faced - There is a form, in which I need to perform server side validations on various fields. I am doing so by firing an ajax request on blur event. Depending upon the server response of validation Ajax fired on blur, fields are marked invalid and form submission is not allowed. (Avoiding 'change' event as that causes alot of overhead on server due to high number of Ajas requests and also leads to fluctuating effects on a field when response from various such Ajax requests are received).

Things are working fine except in one case - when user modifies the value of a field and instead of 'tab'bing out from the field she directly clicks at the save button. In such a case, though, the blur event gets fired but the processing of 'Save' doesn't wait for Ajax Validation response and submits the form. Thus, I somehow need to check if Ajax requests have finihed loading and the process the saving of form. requestComplete would unfortunately not serve the purpose here. And if try using the recursion, then of course, the browser is hung due to high usage of resources. Same case occurs if I try using a pause script work around ( as shared here - Javascript Sleep).

Any possible workaround for this one?

TIA

netemp
  • 4,115
  • 12
  • 43
  • 63
  • Please add a comment if voting down. That would help to improve what is missing in the question. Thanks. – netemp Nov 19 '11 at 12:40
  • After evaluating the things, I found that this is the same old demand of expecting a sleep function in Javascript :) As discussed here - http://stackoverflow.com/questions/5832276/why-there-is-no-sleep-functionality-in-javascript-when-there-is-settimeout-and-s - and at many other places. I wonder, that though JS is a single threaded language, but given the presence of Ajax should there not be such a functionality present to pause the things in JS if required? Writing code in request complete event may not always serve the purpose as shared in the situation above. – netemp Nov 21 '11 at 05:59

4 Answers4

2

Your method will lead to infinite recursion.

A better way is to register a callback function in Ext.Ajax.requestcomplete, something like this (not tested):

Ext.Ajax.on('requestcomplete', function(conn, response, options) {
   if (!Ext.Ajax.isLoading()) {
      //your action...
   }
}

};

msanford
  • 11,803
  • 11
  • 66
  • 93
Eivind T
  • 1,059
  • 9
  • 14
  • Thanks for the post Eivind. Unfortunately, the situation I am facing (added details in question above), in that requestComplete would not fit. Any possible work around in such a situation? Thanks for time again. – netemp Nov 21 '11 at 05:25
1

Unless I am misunderstanding the issue couldn't you create a couple of globals. I know globals are bad, but in this case it will save you quite a bit of headache. One global would be "formReady" and initially set it to false, the other would be "ajaxActive" and set to false. You would also add an onSubmit method that would validate that "formReady" was true and if not alert the user that validation was occurring (or you could set a timeout for form submission again and have a second validation that checks to see if "ajaxActive" is true). When the AJAX call is made it would set the variable "ajaxActive" to true and once complete would set formReady to true. You could also potentially resubmit the form automatically if the response from the AJAX was that the form was good.

Stacy
  • 11
  • 1
0
if (Object.keys(Ext.Ajax.requests).length === 0) console.log("No active requests");
0

Ext.Ajax.request() returns a transaction object when you call it, which is unique and allows you to recognise and abort specific Ajax requests.

By just calling Ext.Ajax.isLoading() without a specified transaction object, it defaults to the last request, which is why you have to call it recursively at the moment.

If it were me, I'd create an array of these transaction objects as you fire them off, and pass each of those in as optional parameters to the Ext.Ajax.isLoading() function to check if a particular request has finished. If it has, you can remove that transaction object from the array, and only progress with the save when your array is empty.

This would get round your recursion problem, since you've always got a finite number of requests that you're waiting on.

Daniel Attfield
  • 2,024
  • 2
  • 24
  • 40
  • Thanks Daniel. That is useful information. But again, the main issue bottoms down to the line - "only progress with the save when your array is empty" - how should I force the JS engine to wait till the array is empty and then execute the save function? I guess that this would again demand recursion and would lead to the same error which I have shared in the question. – netemp Nov 23 '11 at 14:03
  • Ah, I understand - so you don't want the user to have to submit the form for a second time; it's not your standard form validation. I guess this is where you could actually use requestComplete() in combination with this solution - your requestComplete() function could contain a check to see if the array is empty after removing the given request from the array. If it is, then proceed with your saving call. – Daniel Attfield Nov 23 '11 at 14:30
  • This could have been a possible solution Daniel, but the situation is that I need to perform this check in 'validateedit' event of 'RowEditing' plug-in. It is this event which fires Ajax for check and it needs to return false if validation fails so that the 'edit' event doesn't get fired. Now, using requestComplete too doesn't prevent 'edit' event from being called as the JS engine itself moves to 'edit' event without waiting for Ajax response (that is, it accepts the input even if invalid) which is not what is expected. – netemp Nov 23 '11 at 14:45