PDA

View Full Version : YAHOO.util.Connect.asyncRequest Alternative



manugoel2003
9 Jan 2007, 10:39 PM
Hi all,

Is there any way of making an AJAX request other than "YAHOO.util.Connect.asyncRequest", through which I can get the ResponseText straight away. I dont want a callback, I simply want the ResponseText.

Something like


var data = YAHOO.util.Connect.asyncRequest('GET', 'www.abc.com/getdata.php');


and maybe return null in the case of failure.... the bottomline is, it is frustrating to create callback functions for every AJAX request I send..... and more so if I have over 50 AJAX calls in different situations.


Thanx

Animal
9 Jan 2007, 11:52 PM
You can use the following hacked function. But think about whether you really need to go synchronous. It can hang your browser. What are you trying to do?



YAHOO.util.Connect.syncRequest = function(method, uri, callback, postData)
{
var o = this.getConnectionObject();

if(!o){
return null;
}
else{
if(this._isFormSubmit){
if(this._isFileUpload){
this.uploadFile(o.tId, callback, uri, postData);
this.releaseObject(o);

return;
}

//If the specified HTTP method is GET, setForm() will return an
//encoded string that is concatenated to the uri to
//create a querystring.
if(method == 'GET'){
if(this._sFormData.length != 0){
// If the URI already contains a querystring, append an ampersand
// and then concatenate _sFormData to the URI.
uri += ((uri.indexOf('?') == -1)?'?':'&') + this._sFormData;
}
else{
uri += "?" + this._sFormData;
}
}
else if(method == 'POST'){
//If POST data exist in addition to the HTML form data,
//it will be concatenated to the form data.
postData = postData?this._sFormData + "&" + postData:this._sFormData;
}
}

// THIS IS THE ONLY DIFFERENT LINE FROM THE STANDARD asyncRequest()
o.conn.open(method, uri, false);

if(this._isFormSubmit || (postData && this._use_default_post_header)){
this.initHeader('Content-Type', this._default_post_header);
if(this._isFormSubmit){
this.resetFormState();
}
}

if(this._has_http_headers){
this.setHeader(o);
}

this.handleReadyState(o, callback);
o.conn.send(postData || null);

return o;
}
};

manugoel2003
10 Jan 2007, 12:13 AM
Thanx Animal.... actually I was working on a dynamic form in which some of my AJAX calls are dependent on each other..... there are some places where the details of an AJAX call are to be decided by another AJAX response..... now there are many such forms, so it was becoming difficult..... thanx

Animal
10 Jan 2007, 12:49 AM
Chain them together in the callback.

manugoel2003
10 Jan 2007, 2:07 AM
I was doing that, but I am running out of names :) ....... there are just so many callback fuctions ..... I am not sure if it is a good idea to sync the requests but I guess I have to give it a try....

Animal
10 Jan 2007, 2:37 AM
It's definitely not a good idea to make requests synchronous.

sjivan
10 Jan 2007, 7:26 AM
Animal,
I use DWR for server side validation of form elements. (See http://www.jroller.com/page/sjivan?entry=register_screen_using_yui_ext )

As the user enters stuff in text boxes, I make an async call to validate the contents and display a success / error message.

The problem however with async calls and form validation is that when the user hits the submit button, one needs to run the validation for all fields and only if all fields are valid should the form be submitted. Since server side validation of each field is async, this becomes hard to do without using Narrrative Javascript (http://neilmix.com/narrativejs/doc/index.html) since there is no wait in Javascript. One can do a recursive setTimeout(..) and check the status of a num fields validated count but my experience with that has been pretty erratic.

So what I've done is build a generic form validation class wich accepts the form name, an array of (field, event, dwr asyc validation function name). eg : [firstName, 'blur', validateName]. So validateName() is called asynchronously when , say, the user changes fields and the appropriate error message is displayed. However when the user clicks submit, this validation helper class basically goes through each field validation routine and toggles the DWR validation routine to be run in synchronous mode.

It would have been an issue if the validation routine was called synchronously when the user changed fields as the "browser freeze" would be noticeable. However when the user submits a form, he's not doing anything but waiting for the form to be processed and the sycn call here is not noticeable and doesn't alter the user experience.

As an aside, I recollect that your DWR - YUI-ext grid integration code also made a sync DWR call to get the rowcount. Has this been an issue for you? Were browser freezes noticeable?

I hope Jack's form library handles both local as well as async server side validation functions for form fields.

Sanjiv

Animal
10 Jan 2007, 8:38 AM
Yes, I use a synchronous DWR call. DWR handles request timeouts and cancels the request if it takes too long, so that prevents hangups.

manugoel2003
10 Jan 2007, 9:33 AM
My problem is quite similar to Sanjiv..... he has just explained it so well

brian.moeskau
10 Jan 2007, 12:22 PM
The problem however with async calls and form validation is that when the user hits the submit button, one needs to run the validation for all fields and only if all fields are valid should the form be submitted.

Hi Sanjiv,

Just curious, what's the reason for this? Are you posting the entire page back when posting the form? If posting via ajax, I would think you could simply post the form and validate on the server (calling a routine that aggregates all of your individual validation methods), returning your errors as a collection if invalid, otherwise saving. It's ultimately the same amount of data being sent, but with fewer connections to the server, plus the interaction is easier to manage. Or am I missing something?

sjivan
10 Jan 2007, 3:12 PM
The problem however with async calls and form validation is that when the user hits the submit button, one needs to run the validation for all fields and only if all fields are valid should the form be submitted.

Hi Sanjiv,

Just curious, what's the reason for this? Are you posting the entire page back when posting the form? If posting via ajax, I would think you could simply post the form and validate on the server (calling a routine that aggregates all of your individual validation methods), returning your errors as a collection if invalid, otherwise saving. It's ultimately the same amount of data being sent, but with fewer connections to the server, plus the interaction is easier to manage. Or am I missing something?

I guess one advantage would be to avoid repeating the code on the server i.e requiring a server side function that is built for each form that does the validation aggregation when such logic is already presented on the client. The Javascript form validation class would now no longer be just a pairing of field and reusable validation routines but would also require an additional routine for each form on the server which basically goes through the the list of fields that require validating.

I'd be more interested in moving to your suggestion if someone could spell out why synchronous calls are not a good idea at the time of submitting the form. I realize that people say that Ajax sync calls are bad, but as I pointed out in my previous post, I can see why validation synch calls are really bad if used onblur or onkeypress but need more convincing on why they are bad during form submission. If anything, they could prevent the user from clicking elsewhere when the form is submitted and even potentially alleviate the double submit problem. People do disable links, buttons, add modal window etc when submitting forms in the traditional way for this very same reason. So if the form submit changes the submit button CSS to be disabled and the call itself is synchronous, I don't see a usability issue. But i'm open to changing to your method if there's a good reason to. I'm also going to give this some more thought.

Sanjiv

tryanDLS
10 Jan 2007, 3:22 PM
Wanting to avoid duplicating validation code on the server is a bad idea. From a security perspective, it's pretty much a given that you have to validate in both places, because a) if javascript is turned off, your validation won't happen (not likely in this case cuz you're building a javascript site), b) if a hacker can submit your page bypassing the clientside validation, he has free reign to submit whatever he wants.

brian.moeskau
10 Jan 2007, 3:30 PM
OK, I did not realize that you were validating on the client -- I misunderstood and thought you were making ajax calls to the server to validate as you went, then trying to make the same ajax calls in sequence on form submit. I agree that you don't want to duplicate logic.

However, you should always validate on the server regardless -- it's too easy for someone to bypass your form by spoofing a POST to the server with arbitrary data. So you're back to duplicating your logic, or perhaps keeping it all on the server and making ajax calls to validate. I have not tried this yet, but it was the route I was going to try myself. Of course, focus/keypress would not be ideal for this, but validating on blur would likely be acceptable. Although, you are validating your user name field on keypress and it seems to work well...


someone could spell out why synchronous calls are not a good idea at the time of submitting the form
Easy -- because the UI will lock up and they will think you broke their browser. Your users aren't on localhost like you are ;) Even with small ajax payloads of data, you still have to contend with network/ISP latency, etc. On a slow day your request could still take a second or two to complete, during which the user can't scroll, tab, etc. While that may seem minor, it's really a crappy user experience given the simple alternative of making it async with absolutely zero UI latency. You are definitely better off disbaling the submit button and doing the call async.

sjivan
10 Jan 2007, 3:53 PM
OK, I did not realize that you were validating on the client -- I misunderstood and thought you were making ajax calls to the server to validate as you went, then trying to make the same ajax calls in sequence on form submit.

Actually I was making the validation call to the server.

I buy your other arguments :) and so will probably change to using your suggestion.

Thanks,
Sanjiv

72
25 Apr 2007, 10:28 AM
Its just an idea, but did you tried to cache responses? U can use event manager in it and tells if all requested requests are done.
After it you can parse it..

request1 -> response1 -> callback -> cache_response1
request2 -> was_requested_request_done? -> request_based_on_response -> response2

in order if request2 was called before so cache parameters and call it after response1 comes

request2 -> was_requested_request_done? -> cache_request_params
request1 -> was_request2_called_before? -> callback -> request2_again



I hope its not offtopic :)

Its offtopic due to date :)

mudit.sharma
24 May 2007, 5:42 AM
hi animal,
i'm using
YAHOO.util.Connect.syncRequest('post', '/tsn/testdownload?tabName='+this.tabName+'&userId='+id, callback,"");

for uploading file. But i need to do it synchronously. Please help.
I tried code you have provided but it didn't work.

thanks