Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modify ajax response before any bound callbacks get executed

ISSUE

I needed a way to modify all ajax responses in an app before all bound callbacks are triggered.

SOLUTION

Standard ajax events, both global and local do not provide a good way to modify the response before app bound callback are triggered.

The order by which ajax events get triggered is the one indicated in the jquery's ajax event docs i.e.

  • ajaxStart (Global Event)
  • beforeSend (Local Event)
  • ajaxSend (Global Event)
  • success (Local Event)
  • ajaxSuccess (Global Event)
  • error (Local Event)
  • ajaxError (Global Event)
  • complete (Local Event)
  • ajaxComplete (Global Event)
  • ajaxStop (Global Event)

Notice that there is no hook executed after the response gets back from the server but before success/erorr callback are run e.g. a kind of ajaxReturn after ajaxSend but before success|error

The way i hacked this was to use $.ajaxPrefilter which is executed before ajaxStart and to wrap the already bound success/error callbacks in another function which will allow me to modify the options object and thus the returned data.

Below is the utility function that does the wrapping and an example:

var alterResponse = function (opts) {
    var callback = function (options, originalOptions, jqXHR) {
        if (options.url.match(opts.urlMatch)) {
            // Cache original callback.
            var originalSuccess = originalOptions.success || options.success;
            originalOptions.success = options.success = function () {
                // Call wrapper that will modify the response object.
                opts.successWrapper.call(null, options, originalOptions, jqXHR, originalSuccess);
            };
        }
    };
    if (opts.dataTypes) {
        $.ajaxPrefilter(opts.dataTypes, callback)
    }
    else {
        $.ajaxPrefilter(callback);
    }
};

alterResponse({
    urlMatch: /myurl/g, // Filter urls you what to tamper with.
    successWrapper: function (options, originalOptions, jqXHR, originalFn) {
        options.data.customVar = 'customValue';
        originalFn(options, originalOptions, jqXHR);
    }
});

I have to mention i'm using this for testing purposes so i'm not concerned about performance, memory and overhead.

like image 880
alexandru.topliceanu Avatar asked Jan 15 '23 08:01

alexandru.topliceanu


1 Answers

If you'd like to modify the data coming back from the server before it reaches the event handler, use dataFilter:

    jquery.ajaxSetup({
        dataFilter: function (data, type) {
            //modify your data here

            return data;
        }
    });
like image 91
Hugo Forte Avatar answered Jan 18 '23 23:01

Hugo Forte