Extending each Ajax.Request onSuccess event (Javascript Prototype Framework)
I have an application that uses Ajax.Request
and its event handler onSuccess
in many places.
I need to call a function (which will check the response) before all these events onSuccess
fire. I tried to use Ajax.Responders.register
with an event onComplete
, but it fires after the event Ajax.Request
onSuccess
. Any suggestions?
source to share
It might be a little overdue, but for someone else interested in the same issue, I suggest this solution:
To do this, you can use Prototypes's own aspect-oriented programming implementation. You will of course have to change all of the onSuccess parameters, but that can be done with a simple find and replace instead of updating all of your callback functions. Here's an example of creating an Ajax.Request:
new Ajax.Request('example.html', {
parameters: {action: 'update'},
onSuccess: this.updateSuccessful
});
Suppose you have similar code snippets distributed throughout your code and you want to outperform them all with a specific function that validates the response before the actual function is fired (or even not fired at all). Using the Funtion.wrap provided by Prototype, we can do this by extending the code above:
new Ajax.Request('example.html', {
parameters: {action: 'update'},
onSuccess: this.updateSuccessful.wrap(validateResponse)
});
Where "validateResponse" is a function like this:
// If you use the X-JSON-header of the response for JSON, add the third param
function validateResponse(originalFn, transport /*, json */) {
// Validate the transport
if (someConditionMet) {
originalFn(transport /*, json */);
}
}
So you've extended the onSuccess functions in one central place with a simple onSuccess search and pasting in 'wrap (validateResponse)'. It also gives you the ability to have multiple wrapper functions depending on the needs of a particular Ajax request.
source to share
similar to Alexander Krzhivinsky's answer, but I believe it would prevent you from sprinkling the use of "wrapper" all over the place by combining it with the onCreate Responder.
Ajax.Responders.register({
onCreate: function(request) {
request.options['onSuccess'] = request.options['onSuccess'].wrap(validateResponse);
}
});
source to share
There are several events that you have chosen from . Here is the chain of events for Ajax.Request
:
-
onCreate
-
onUninitialized
-
onLoading
-
onLoaded
-
onInteractive
-
onXYZ
,onSuccess
oronFailure
-
onComplete
onLoading
, onLoaded
, onInteractive
It sounds interesting, but according to the specification , they are not guaranteed. This gives you the ability to connect to onCreate
, which is called immediately after the request object is built, but before the request is actually made.
source to share
Don't know if this is the cleanest solution, but for me this is the trick.
var tmp = Ajax.Request;
Ajax.Request = function(url, args) {
// stuff to do before the request is sent
var c = Object.clone(args);
c.onSuccess = function(transport){
// stuff to do when request is successful, before the callback
args.onSuccess(transport);
}
var a = new tmp(url, c);
return a;
}
Ajax.Request.protoype = new tmp();
Ajax.Request.Events = tmp.Events;
delete tmp;
source to share
"Generic solution" - regardless of JS structure (kind)
var oldFunc = Ajax.Request.onSuccess;
Ajax.Request.onSuccess = function foo() {
alert('t');
oldFunc.apply(this, arguments);
}
This will "extend" your JS function, causing it to do exactly what it used to, except to display an alert box every time before it is executed ...
source to share