Trigger an event upon the completion of any AJAX request

Seeking to observe the onComplete event of all AJAX requests externally without being within the individual requests.

Wanting to trigger an event when any or all AJAX requests finish.

Is this achievable?

Many thanks, Tim

Edit: Only using Mootools library (v1.4)

Answer №1

If you're looking to simply observe and intercept, the process can be a bit tricky. However, the code required is relatively straightforward. One option for making changes to a single Request prototype would be to use Class.refactor from mootools-more, if it's accessible:

// enable log func...
Class.refactor(Request, {
    success: function(text, xml){
        this.previous(text, xml);
        Request.monitor && typeof Request.monitor == "function" && Request.monitor.apply(this, arguments);            
    },
    failure: function(){
        this.previous();
        Request.monitor && typeof Request.monitor == "function" && Request.monitor.apply(this, arguments);            
    }
});

The following section of code remains consistent regardless of your approach.

// assign a logger function
Request.monitor = function() {
    console.log("onComplete", this.response.text);
};

// call a simple request object.   
new Request({
    url: "/echo/html/",
    method: "post",
    data: {
        html: "hello"
    }
}).send();

The advantage here is that it will remain functional even if there are tweaks to mootools-core. It doesn't rely on the specifics of the core functionality, ensuring it continues running smoothly unless there's a major API alteration down the line.

You could also opt to modify classes using implement instead, but this approach may not accommodate mootools-core modifications. Essentially, this entails duplicating the current function within the methods and then appending any desired changes - particularly useful for shorter functions we intend to modify:

Request.implement({
    success: function(text, xml){
        this.onSuccess(this.processScripts(text), xml);
        Request.monitor && typeof Request.monitor == "function" && Request.monitor.apply(this, arguments);            
    },
    failure: function(){
        this.onFailure();
        Request.monitor && typeof Request.monitor == "function" && Request.monitor.apply(this, arguments);            
    }
});

Finally, you have the option to preserve the original low-level functionality with

var oldsuccess = Request.prototype.success
, make your adjustments, and execute
oldsuccess.apply(this, arguments)
.

The challenge arises when dealing with subclasses like HTML and JSON which might have already mirrored the old prototype, rendering your logger ineffective. A potential solution involves implementing a small object across all Request classes to address this issue.

An elegant method that could work involves combining elements of the last method with the original prototype, especially since the success functions vary among all three:

(function() {
    var changes = {
        success: function(text, xml){
            this.onSuccess(this.processScripts(text), xml);
            Request.monitor && typeof Request.monitor == "function" && Request.monitor.apply(this, arguments);            
        },
        failure: function(){
            this.onFailure();
            Request.monitor && typeof Request.monitor == "function" && Request.monitor.apply(this, arguments);            
        }
    };

    [Request, Request.HTML, Request.JSON].invoke('implement', changes);
})();

In terms of practical implementation, consider the final version or refactor tailored for production, tested and operational across all three classes. Be mindful that these alterations occur before additional processing for JSON or HTML takes place, positioning it as a low-level logging system. Alternatively, adjust the structure to post-process after onSuccess and onFailure instead.

(function() {
    // Define extensions
    var classes = [Request, Request.HTML, Request.JSON],
        mapper = ["Request", "Request.HTML", "Request.JSON"],
        orig = {
            onSuccess: Request.prototype.onSuccess,
            onFailure: Request.prototype.onFailure
        },
        changes = {
            onSuccess: function(){
                Request.Spy && typeof Request.Spy == "function" && Request.Spy.apply(this, arguments);
                orig.onSuccess.apply(this, arguments);
            },
            onFailure: function(){
                Request.Spy && typeof Request.Spy == "function" && Request.Spy.apply(this, arguments);
                orig.onFailure.apply(this, arguments);
            }
        };

    classes.invoke('implement', changes);

    // Determine which Class prototype triggered the AJAX call
    Request.implement({
        getClass: function() {
            var ret;
            Array.each(classes, function(klass, index) {
                if (instanceOf(this, klass)) {
                    ret = mapper[index];
                }
            }, this);
            return ret;
        }
    });
})();

// Enable spying by defining Request.Spy as a function:
Request.Spy = function() {
    console.log(this.getClass(), arguments);
};

// Test through a standard Request
new Request({
    url: "/echo/html/",
    data: {
        html: "normal data"    
    }
}).send();


// Test via HTML
new Request.HTML({
    url: "/echo/html/",
    data: {
        html: "<p>normal data</p>"    
    }
}).send();

// Test via JSON
new Request.JSON({
     url: "/echo/json/",
     data: {
        json: JSON.encode({'normal':'data'})    
     }
}).send();

JsFiddle link: http://jsfiddle.net/dimitar/3rnKe/

Answer №2

Note: This code is specifically designed for jQuery and may not work with MooTools.

$(document).ajaxComplete(function() {
  $(this).text('This is the ajaxComplete handler in action.');
});

For more information, refer to: http://api.jquery.com/ajaxComplete/

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Arrange objects in an array by the date field using Meteor

I have updated my user collection in my Meteor app with an array of objects named contacts. This is how it looks now: { "_id" : "p6c4cSTb3cHWaJqpG", "createdAt" : ISODate("2016-05-11T11:30:11.820Z"), "services" : { ..... }, ...

It appears that the query parameters are impacting the speed at which the page loads

I am currently developing a project on this platform. It is using c9.io, an innovative browser-based collaborative programming IDE. The index.php file includes the following script: <?php $path = ltrim($_SERVER['REQUEST_URI'], '/&ap ...

The issue of req.file being undefined when using Multer in Node.js with Express Router

I have been working on incorporating File Upload capability utilizing multer and Express Router. I set up an endpoint /batch_upload using router.use in the following manner: api.js router.use( "/batch_upload", upload.single("emp_csv_data"), userCo ...

Display a pop-up notification to a user one time

Looking to enhance the user experience on my website, I want to display a pop-up alert only during the first visit and not on subsequent visits. As someone with limited HTML and scripting skills, can you guide me on how I can achieve this using cookies or ...

Duplicating a concealed div and transferring it to a new div

I'm encountering an issue while trying to copy one div to another. The div I'm attempting to copy has a hidden parent div. The problem is that the destination div does not appear after copying, even though I changed its style display to block. ...

The glow shader for front face is not displaying correctly in Chrome, but it functions fine in other web browsers

I have encountered an issue where I am attempting to apply a custom shader material to a series of nested objects in order to create a glow effect around each node. The effect works perfectly on my personal laptop (running Windows 8.1 and the latest versio ...

I am looking to save the data entered in an HTML form directly into a JSON file within the webpage

I am currently storing the value in an array on the server, but I would like to store it only on the client side within the webpage. I want to write the form data from the HTML form into a JSON file that remains on the page itself and is not sent to the ...

jquery kwicks problem

I have been grappling with a coding problem for hours on end and I have hit a wall. Assistance is needed. On a staging page, the code was tested and found to be functioning properly. However, on the live page, the same code fails to respond as expected. I ...

How to remove a variable definition in Typescript

Is there a way to reset a variable to undefined after assigning it a value? To check, I am using the Underscore function _.isUndefined(). I have attempted both myVariable = undefined and delete myVariable without success. ...

Modify the color of the chosen option in the dropdown menu without affecting the rest of the options

I am facing an issue with dynamic drop down lists in my HTML content. The requirement is to change the color of the selected option to dark red if the option is "success". I have implemented a jQuery function for this purpose. HTML: <select class="rea ...

Cross-Origin Request Sharing (CORS) problem encountered while making an API call with

My current challenge involves calling an API that returns data in XML format as a response. While testing the .htm file on my local machine, I encountered the following error. https://i.stack.imgur.com/FsvZ0.png Similarly, running it from the codepen.io ...

Mock needed assistance

In my testing scenario, I am attempting to simulate a service that is utilized by my function using sinon. However, I am encountering difficulties in inserting the mock into my function. The service is obtained through the use of require The structure of ...

Filtering a collection in Firestore using the `where()` method for a context provider in Next.js

i encountered an issue: when using the useEffect function to retrieve my firestore documents, it works well. Currently, I am fetching all "profiles" documents (3 in total). However, I now want to only retrieve the documents where the field "workerProfile" ...

Protecting your application with Spring security and integrating Ajax functionalities

My spring security setup currently redirects to the login page when a user is not authenticated: <form-login login-page="/login/" authentication-failure-handler-ref="customAuthenticationFailureHandler" authentication-success-handler-ref="custom ...

Is it justifiable to stop providing support for javascript-disabled or non-ajax browsers in secure applications?

I'm intrigued by the current trend in ajax applications. Is it acceptable to focus on building the best ajax application possible and disregard browsers that don't support ajax (especially if it's a secured part of the site and not public)? ...

Verifying PHP session through AJAX

How can I execute an AJAX request to run an INSERT query? The query requires a value from a PHP session, but the JavaScript request does not recognize that value. Why is this happening and what steps should I take? See some of the code below: JS: $(&apo ...

AngularJS and IE8 don't play nice when it comes to handling dynamic content

Below is the code snippet I am working with: <blockquote class='mt20'> <p><span>&ldquo;</span><span>{{iq.quote}}</span><span>&rdquo;</span></p> <footer><cite class="d ...

Having trouble with the post request in Express JS and Vue? Don't worry, we've got you covered

I've been following a tutorial to set up a basic app and everything is working smoothly, except for the post request which seems to be causing me trouble. Tutorial: https://www.youtube.com/watch?v=HkIGAqAP1GY Although the issue is reproducible based ...

Error in zone: 140 - Property 'remove' is not readable

I'm brand new to kendo ui. I successfully set up a prototype in my fiddle with a working delete confirmation window. However, when I try to integrate it into my existing codebase, I encounter an error: Cannot read property 'remove' at the li ...

Guide to moving a 3D model and initiating animation in threejs when a key is pressed

In the midst of a project where a person (gltf object) walks based on key presses, I have successfully updated the object position accordingly. However, I'm encountering difficulty in rotating the object when the left/right keys are pressed and ensur ...