views:

7862

answers:

7

Hi all,

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

I have two functionsm 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) {

}

Sorry if this is hard to understand. Basically I just want to be able to pass in my own parameters to a callback, as well as the result returned from the AJAX call.

Thanks!

A: 

actually, your code is not working because when you write:

$.post("someurl.php",someData,doSomething(data, myDiv),"json");

you place a function call as the third parameter rather than a function reference.

Here Be Wolves
+2  A: 

You can also try something like the following:

function clicked() {

    var myDiv = $("#my-div");

    $.post("someurl.php",someData,function(data){
        doSomething(data, myDiv);
    },"json"); 
}

function doSomething(curData, curDiv) {

}
Rohan Almeida
+15  A: 

When using doSomething(data, myDiv), you actually call the function and does not make a reference to it.

You can either pass the doStomething function directly but you must ensure it has the correct signature.

If you want to keep doSomething the way it is, you can wrap its call in an anonymous function.

function clicked() {
    var myDiv = $("#my-div");
    $.post("someurl.php",someData, function(data){ 
      doSomething(data, myDiv)
    },"json"); 
}

function doSomething(curData, curDiv) {
    ...
}

Inside the anonymous function code, you can use the variables defined in the enclosing scope. This is the way Javascript scoping works.

Vincent Robert
+4  A: 

You can use a closure of JavaScript:

function wrapper( var1, var2,....) // put here your variables
{
  return function( data, status)
  {
     //Handle here results of call
  }
};

and when you can do:

$.post("someurl.php",data,wrapper(var1, var2, etc...),"html");
Artem Barger
+15  A: 

The solution is the binding of variables through closure.

I haven't used the .post function in jQuery, but a quick scan of the document suggests the call back should be a function pointer accepting the following:

function callBack(data, textStatus) {};

Therefore I think the solution is as follows:

var doSomething = function(extraStuff) {
    return function(data, textStatus) {
        // 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.

bradhouse
Thanks for the explanation -- that was really helpful!
Jasie
What is the purpose of 'var doSomething = '? How is this different from just declaring doSomething as a function (ie function doSomething(...) {} )
ranomore
It isn't different really. "function foo() {};" is syntactic sugar for "var foo = function() {};". That said, I tend to prefer the var syntax especially when you're passing around the function as data.
bradhouse
A: 

function custom_func(p1,p2) { var local='test'; $.post(AJAX_FILE_PATH,{op:'dosomething',p1:p1}, function(data){ return function(data){ alert(p2); alert(local); }(p2,local) } ); }

Igor
A: 

I've made a mistake in the last my post. This is working example for how to pass additional argument in callback function:

function custom_func(p1,p2) {
    $.post(AJAX_FILE_PATH,{op:'dosomething',p1:p1},
        function(data){
            return function(){
                alert(data);
                alert(p2);
            }(data,p2)
        }
    );
    return false;
}
Igor