Prototype: Ajax.Request w/asynchronous: false

All,

I have the following Ajax call:

new Ajax.Request(action, {asynchronous: false,
method: ‘post’,
parameters: params_to_pass,
evalScripts: true});

The action that I’m calling is using render :update to send back
Javascript. When asynchronous is set to true above, then the Javascript
is executed (because of evalScripts: true). However, when asynchronous
is false as above, the evalScripts true doesn’t appear to automatically
allow the Javascript to be run.

I’m going to add a onComplete callback to get around my issue, but I was
just wondering if someone could explain the relationship between
asynchronous and evalScripts that I think I’m seeing.

Thanks,
Wes

I can’t get an onComplete callback to be executed when using
asynchronous:false with Ajax.Request either.

I’m using Prototype 1.5.0rc0.

Anyone know if this is a known issue?

Wes

My bad. I can get the onComplete callback to be called.

Perhaps my understanding of evalScripts is flawed. I will attempt to
correct it.

WG

Doesn’t setting asynchronous to false block on the Ajax.Request call?

I have this:

//Call the passed in action
new Ajax.Request(action, {asynchronous: false, method: ‘post’,
parameters: params_to_pass, evalScripts: true, onComplete:
function(request) {eval(request.responseText);}});

if (print_action) {
submit_form_to_popup(form, print_action, params_to_pass);
}

Execution continues as though I had called the Ajax.Request with
asynchronous:true. Is that expected?

Wes

The blocking does occur, BUT callbacks are not called when asynchronous
is set to false.

Here’s some discussion on this issue.

http://dev.rubyonrails.org/ticket/4657

Can anyone corroborate (or much better, refute) the statement

“Callbacks are not invoked on synchronous calls of Ajax.Request”

Thanks,
Wes

You are correct Wes, callbacks are not called when asynchronous is set
to false. About a month or two ago I actually ran into this same
problem and went wandering around the code for Prototype. If I
remember correctly, there was some code that basically said “If
asynchronous is false, then don’t bother with the callbacks”.

I can’t speak for the Prototype developers, but I suspect the
reasoning for doing that was because of how a synchronous call would
be used. When I used it in my own code it was basically this way:

/* Some initialization code /
var req = Ajax.Request(…) // Synchronous call
/
Do some stuff with the data returned in ‘req’ */

After the request finishes, you can do things like call
req.responseIsFailure() to determine if you did or did not get a 200
back from the server. Also, req.transport is the original
XMLHTTPRequest object, so req.transport.responseText will give you the
data sent back from the server.

Hi Wes,

Wes G. wrote:

Doesn’t setting asynchronous to false block on the
Ajax.Request call?

I haven’t looked into the guts of this but given that the ‘A’ in Ajax
stands
for asynchronous, I’d bet …

Best regards,
Bill

Hooray! I upgraded to Prototype 1.5 (I was on 1.5rc0) and the callbacks
were invoked on the synchronous call.

Jeff,

Thanks for the response. I did not know how to get
transport.responseText from the variable that you set to be the updater
object. Obviously, I could use that if the fix that I just found didn’t
work.

Good stuff - thanks.

Wes

This is correct, and can be pretty hard on the user… If you make an
Ajax.Request with asynchronous set to false, and it hangs people using
Firefox will not be able to properly close their browsers. Firefox
currently has a bug open for this very issue. Luckily IE ans Safari
will kill the request no matter where it is and close the browser just
fine but I wouldn’t leave out all of those Firefox users…

Generally speaking, do not ever use synchronous ajax calls in
production code, as the browser will block completely.
As in, if the connection hangs for some reason, the browser is
basically dead meat and hangs (depends on the browser, though).

Best,
Thomas

Am 02.03.2007 um 21:21 schrieb Jeff A.:

Thanks for the advice.

In my case, I want to have the user click a button, which causes a form
post, and then depending on whether the form data were updated
successfully, open up a popup and display a PDF.

I need to use AJAX in order to be able to communicate across two
requests in Javascript, and I need the first call to be synchronous so
that I can determine whether it completed correctly before firing off
the 2nd (async.) request.

I couldn’t see a better way to do it.

Wes

You might want to delve into the onXXX (onFailure, onLoaded,
onComplete, onException, etc) properties of the Ajax.Request call. You
can check for all sorts of status’ form the AJAX request.

(Scroll down a bit.)

You can assign an anonymous function to these properties detailing
(using JavaScript) how to handle these situations. This way you should
be able to capture enough of the issues and goals of your AJAX
request, without making it a synchronous call. For example you could
make an onComplete that looks like this:

onComplete: function( responseText )
{
// Passes the data from recieved form the server on the first AJAX
call to a function invoking the second AJAX call.
makeSecondAjaxCall( responseText );
}

Hope that helps.
-John

On Mar 2, 11:46 pm, Wes G. [email protected]

John,

That was my original approach. Unfortunately, the 2nd function needs to
open a popup window and popup blockers will be engaged if you go that
route (apparently because you are calling the window.open from a
different function - the callback function, than the first JS function).

I decided to do the synchronous 1st AJAX call out of necessity, not out
of convenience.

Thanks for the feedback.

Wes