0

This is what I have:

function populateElement(arg1) {

    getData(arg1); 
}

function getData(query) {

    var url = "http://foo" + query + "&callback=processData";
    // do stuff 
}

function processData(results) {

    callbackForGetData(results); 
}

function callbackForGetData(result) { 

    // process data 
}

I want to pass two more arguments to function populateElement like so:

function populateElement(arg1, arg2, arg3) {

    getData(arg1);
}

And have the arg2, arg3 available in callbackForGetData

function callbackForGetData(result) {

    // process data
    // use arg2, arg3 here
}

How should I do this?

4
  • Why not call getData directly? Commented Jul 14, 2011 at 6:34
  • possible duplicate of Appending multiple parameters/arguments to a jsonp callback function. I offered an outline of a solution in an answer to this question. Commented Jul 14, 2011 at 6:38
  • @Adam: The problem is that callbackForGetData is being called as a JSONP callback so the OP doesn't have any control over how it is called. Commented Jul 14, 2011 at 6:42
  • mu is too short - First, this is not a repost. I'm new to JS and callbacks and I really don't understand what you mean by "doesn't have any control over how it is called". I can change the callbackForGetData. Commented Jul 14, 2011 at 7:41

4 Answers 4

0

You can pass them on to the callback and access them in the arguments array

function getData(result) {
  //result === arg1
  //arguments[0] === arg1
  //arguments[1] === arg2
  //arguments[2] === arg3
  //and so on
}

getData(arg1, arg2, arg3);
Sign up to request clarification or add additional context in comments.

5 Comments

His question is how you get arg1, arg2, and arg3 in his callback function.
I realize that, but i'm assuming that he doesn't want to, or can't change the callback, otherwise he could add parameters to getData and use them
This won't work. The problem is that the callback is getting called through JSONP. You need to do something like this.
how did you find that out? It doesn't say it in the question... :|
@James I'm really confused with the callbacks. I can change the callback function. Could you give an example? Thanks.
0

Pass an object as a single paramater:

function populateElement(arg1, arg2, arg3) {

    var params = {"arg1":arg1,"arg2":arg2,"arg3",arg3};
    getData(params);
}

function getData(params) {

    var query = params.arg1;
    var url = "http://foo" + query + "&callback=processData";
    // do stuff 
}

Comments

0

Your are looking for a closure.

function getData(query) {
    var url = "http://foo" + query + "&callback=processData";
    // do stuff
    //simulate the callback
    processData("some results");
};

function populateElement(arg1, arg2, arg3) {
    //Because we define processData here, we have a closure scope that
    // lets us see all the arguments to populateElement
    window.processData = function(results) {
        console.log("ProcessData called with results: " + results +
            ", arg2: " + arg2 + ", arg3: " + arg3);  
    };
    getData(arg1);
}
//Simulate the starting call
populateElement(4, 5, 6);

Here's a working jsfiddle.

Note this only supports a single (1) pending getData call. A more elaborate scheme would be necessary to support multiple concurrent pending getData calls. Each would need a unique callback closure name, which could be as simple as a trailing numeric serial number.

1 Comment

I need to define a function nested within populateElement so I have access via closure to the populateElement arguments. I assign explicitly to window because being explicit like that is the clearest and least-confusing thing to do. Otherwise the JS default behaviors are well-known to be confusing, so best avoid ambiguity or unexpected/implicit behavior. Just my personal guideline.
0

To pass more arguments, you can use call or apply.

function log(a, b, c) { console.log('A: ', a, ', b: ', b, ', c: ', c);}

log.call(window, 'first', 'second', 'third');
> A:  first , b:  second , c:  third

log.apply(window, ['first', 'second', 'third'])
> A:  first , b:  second , c:  third

But as Peter has suggested, you have some async stuff going on here and you want to save this on a closure, instead of passing extra arguments.

Have something like this, save your data in a closure:

function processData(results) {
  // transform data
  myModule.callbackForGetData(results); 
}

window.myModule = {

  populateElement: function(arg1, arg2, arg3) {

    this.data = arguments;
    this.getData(arg1); 
  },

  getData: function(query) {

    var script = document.createElement('script');
    script.src = 'http://jsfiddle.net/echo/jsonp/?query=' + query + '&callback=processData';
    document.getElementsByTagName('head')[0].appendChild(script)
  },

  callbackForGetData: function(result) { 

      // process data 
      console.log('Args: ', this.data, ', remote result: ', result);
  }
}

// test it
myModule.populateElement(1, 2, 3)
> Args:  [1, 2, 3] , remote result:  Object {query: "1"}

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.