-1

Suppose I have this as an option to a jQuery widget:

    function oneFunc()
    {
     var myVar;

       //there is some widget calling
       $.widget("ui.combobox", $.ui.autocomplete, {
                options: {
                       source: function (request, response){////doing something with myVar, request and response}
                }
       });
    }

Now I want to separate out the function (request, response) using callback

So, I want something like this:

function oneFunc()
{
     var myVar;
     //there is some widget calling
        $.widget("ui.combobox", $.ui.autocomplete, {
                options: {
                       source: myCallBack
       });
}

function myCallBack(request, response){
//I can get request and response here by default but not myVar
//doing something with myVar, request and response
}

So, I can't access myVar. I have to pass it there. but how to do that?

EDIT: I don't want to use global variables request, response are default values that I can get in myCallBack anyway.

Better if anonymous function can be avoided.

3
  • source: myCallBac is not a valid JS statement. Commented Jul 8, 2013 at 11:40
  • myCallBack anyway Better if anonymous function can be avoided.....you already have an anonymous function ..here function myCallBack(request, response){ Commented Jul 8, 2013 at 12:09
  • I guess it has a name- myCallBack Commented Jul 8, 2013 at 12:11

3 Answers 3

2

You can do this by using Function.apply or Function.call

function oneFunc(myCallback)
{
     this.myVar = 1;
    var request = "request";
    var response = "response"
     //there is some widget calling
     myCallback.apply(this,[request,response]);
}

function callback(request, response){
   console.log(request);
    console.log(response);
    console.log(this.myVar);
}

oneFunc(callback);

The above outputs

request
response
1

As you have delegated the this keyword to the callback method allowing it to access any variables declared in the original method.

Live example: http://jsfiddle.net/hFsCA/

Note the apply line can also be replaced with (Thanks @AlessandroVendruscolo)

myCallback.call(this,request,response);

Not that it makes too much difference - but for completeness!

So wrapping that back into your (now updated) example:

function oneFunc(callback)
{
   this.myVar = 1;
   var self = this;
   //there is some widget calling
   $.widget("ui.combobox", $.ui.autocomplete, {

            options: {
                 source: function (request, response){
                        callback.call(self,request,response);
                 }
            }
   });

}
Sign up to request clarification or add additional context in comments.

5 Comments

I'd use call, because you're creating one array that is not really needed. myCallback.call(this,request,response);
request and response are not local to the function. they are only accessible after source is there. So request is undefined there.
Yeah! in that case I don't need to use call also. I can just send the variable. But I don't want to use anonymous function.
@soham.m17 - you're not making any sense. Of course you could just send the variable - I guess the advantage is that if you had 100 variables they would all be accessible in the this context. Not sure what you mean by "anonymous function". In any case, you asked a question and got an answer. If you don't like the answer think up a better question.
Well, the question states "how to pass additional arguments to callbacks..." I don't think your answer addresses that thing in particular. Anyway, it's a good solution avoiding the main course. Thanks.
2

If you want to access myVar inside your separated callback function, I would make it explicit in the declaration:

function myCallBack(request, response, myVar) 
{
}

This makes it easier to keep track of when you see it in your code later on. Then, you write a proxy function like this:

source: function(request, response) {
    return myCallBack.call(this, request, response, myVar);
}

If you want a more complex scope or myVar needs to be changed in both scopes, you need an object:

var myScope = {
    myVar: null
};

// ...

source: function(request, response) {
    return myCallBack.call(this, request, response, myScope);
}

Then, inside the callback:

function myCallBack(request, response, myScope) 
{
    // use myVar as myScope.myVar
}

5 Comments

Actually it would be better if I can pass the argument to the callback not using any anonymous function. Although this thing works. But I don't want to use anonymous function. What I am thinking is that we can just place myCallBack inside oneFunc() also. That also solves the problem. As myVar then would be in scope of myCallBack also. But again, that's not elegant code.
@soham.m17 This is starting to sound like an XY problem; you don't like to use anonymous functions, but obviously the state inside oneFunc() must be somehow transferred. What exactly does myVar contain, what are you writing?
It's a simple string. That is modified in myCallBack.
No, myVar is sent to myCallBack and reused in oneFunc() again. I think I am sounding ambiguous. I simply want to use call backs with additional parameter capability.
@soham.m17 Well, then you need anonymous functions to gather the scope used for your callback, it's as simple as that.
1

I don't if jQuery is internally using any anonymous function or not. But I solved it by this:

function oneFunc()
{
     var myVar;
     //there is some widget calling
        $.widget("ui.combobox", $.ui.autocomplete, {
                options: {
                       source: $.proxy(myCallBack, this, myVar)
       });
}

function myCallBack(myVar, request, response){
//I can access myVar, request and response
//doing something with myVar, request and response
}

Other experienced people can comment on this, I guess.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.