jQuery pass more parameters into callback

atp picture atp · Jun 2, 2009 · Viewed 202.7k times · Source

Is there a way to pass more data into a callback function in jQuery?

I have two functions and I want the callback to the $.post, for example, to pass in both the resulting data of the AJAX call, as well as a few custom arguments

function clicked() {
    var myDiv = $("#my-div");
    // ERROR: Says data not defined
    $.post("someurl.php",someData,doSomething(data, myDiv),"json"); 
    // ERROR: Would pass in myDiv as curData (wrong)
    $.post("someurl.php",someData,doSomething(data, myDiv),"json"); 
}

function doSomething(curData, curDiv) {

}

I want to be able to pass in my own parameters to a callback, as well as the result returned from the AJAX call.

Answer

bradhouse picture bradhouse · Jun 2, 2009

The solution is the binding of variables through closure.


As a more basic example, here is an example function that receives and calls a callback function, as well as an example callback function:

function callbackReceiver(callback) {
    callback("Hello World");
}

function callback(value1, value2) {
    console.log(value1, value2);
}

This calls the callback and supplies a single argument. Now you want to supply an additional argument, so you wrap the callback in closure.

callbackReceiver(callback);     // "Hello World", undefined
callbackReceiver(function(value) {
    callback(value, "Foo Bar"); // "Hello World", "Foo Bar"
});

Or, more simply using ES6 Arrow Functions:

callbackReceiver(value => callback(value, "Foo Bar")); // "Hello World", "Foo Bar"

As for your specific example, I haven't used the .post function in jQuery, but a quick scan of the documentation suggests the call back should be a function pointer with the following signature:

function callBack(data, textStatus, jqXHR) {};

Therefore I think the solution is as follows:

var doSomething = function(extraStuff) {
    return function(data, textStatus, jqXHR) {
        // do something with extraStuff
    };
};

var clicked = function() {
    var extraStuff = {
        myParam1: 'foo',
        myParam2: 'bar'
    }; // an object / whatever extra params you wish to pass.

    $.post("someurl.php", someData, doSomething(extraStuff), "json");
};

What is happening?

In the last line, doSomething(extraStuff) is invoked and the result of that invocation is a function pointer.

Because extraStuff is passed as an argument to doSomething it is within scope of the doSomething function.

When extraStuff is referenced in the returned anonymous inner function of doSomething it is bound by closure to the outer function's extraStuff argument. This is true even after doSomething has returned.

I haven't tested the above, but I've written very similar code in the last 24 hours and it works as I've described.

You can of course pass multiple variables instead of a single 'extraStuff' object depending on your personal preference/coding standards.