2

How do I specify more arguments to be passed to a jsonp callback function?

For example, I'm trying to grab youtube video data:

http://gdata.youtube.com/feeds/api/videos/gzDS-Kfd5XQ?v=2&alt=json-in-script&callback=youtubeFeedCallback

The javascript callback function that will be called is youtubeFeedCallback and it contains only one argument when called.

As of now the function would be something like this,

function youtubFeedCallback(response) {
...
}

What I would like to be able to do is pass a second argument like this,

function youtubeFeedCallback(response, divId) {
...
}

Is this possible to do. I've tried looking everywhere online and couldn't find anything. Thanks!

1
  • The Youtube URL call is being done with an inline script tag. I'm making multiple video entry calls and need to pass a divId so I know which div element to use to put in the returned json video data. I would really like to pass in the divId at the time that the youtube URL is being called. Commented Jul 2, 2011 at 17:01

3 Answers 3

5

You can't add arguments to the callback function like that. However, you can generate a wrapper function. The JSONP callback function just was to be a function in the default namespace, that means that you just need to add a generated function with a known name to the global window object. Step one is to make up a name:

var callback_name = 'youtubeFeedCallback_' + Math.floor(Math.random() * 100000);

In the real world you'd want to wrap that in a loop and check that window[callback_name] isn't already taken; you could use window.hasOwnProperty(callback_name) to check. Once you have a name, you can build a function:

window[callback_name] = function(response) {
    youtubeFeedCallback(response, divId);
};

You'd want to that up a little bit more though:

function jsonp_one_arg(real_callback, arg) {
    // Looping and name collision avoidance is left as an exercise
    // for the reader.
    var callback_name = 'jsonp_callback_' + Math.floor(Math.random() * 100000);
    window[callback_name] = function(response) {
        real_callback(response, arg);
        delete window[callback_name];  // Clean up after ourselves.
    };
    return callback_name;
}

Once you have something like that wired up, you could just call:

jsonp = jsonp_one_arg(youtubeFeedCallback, divId);

And then use the value of jsonp as the callback value in the YouTube URL.

You could build more functions like this to handle longer arguments lists too. Or you could build a general purpose one with arguments and apply.

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

5 Comments

How would I be able to pass in the second argument at the time that the YouTube URL is called? I'm placing the YouTube URL as the src attribute of an inline script tag so it will execute as the page is loading and retrieve the necessary video data in jsonc format. I need the second argument to figure out which div element I will be placing that data in. Thanks!
@Jenn: Could you use an onload handler to set the src attributes? Start the page off with the http://gdata.youtube.com/... URLs in, say, data-src attributes, then your onload handler could transfer the data-src attributes to src attributes while calling jsonp_one_arg and patching up the callback parameter before setting src.
+1: but why using random instead of a simple counter creating say "jsonp_1", "jsonp_2", ... ?
@6502: Just so you don't have to keep track of which ones you've used. You could use a global counter if you wanted sequential ones, or you could loop through window looking for an open slot I suppose.
@6502: You could of course track the sequence number in a jsonp_one_arg.sequence_number property if you didn't want a global. But then you'd have to limit yourself to only jsonp_one_arg or go with the full blown general n-argument callback generator.
0

better way is specify an associated array of divId and videoId like this

var arr = {
    'gzDS-Kfd5XQ': 'divId_1',
    'gwWS-Gasfdw': 'divId_2'
};

and in callback function get your divId by videoId

function youtubFeedCallback(data)
{
    var divId = arr[data.entry.media$group.yt$videoid.$t];
}

1 Comment

This would almost work except, If there was multiple array keys with the same videoid, I would get the correct divId. For example. If var arr = { "gfefe-eee": 'divId_1', "gfefe-eee": 'divId_2' }; I have to worry about the same video data appearing in separate div's. Thanks, though.
0

When creating a "script" object, you can add attributes to it, and reference them later with document.currentScript. This worked for me but other people may need something more elegant.

function blah(stuff,extraarg){
    cs=document.currentScript;
    console.log(stuff); // stuff is your json output
    console.log(cs.extraarg); // cs.extraarg is your extra arg
}

function thing(extraarg){
    var url='https://....&json_callback=blah';
    var s=document.createElement('script');
    s.src=url;
    s.extraarg=extraarg;
    document.body.appendChild(s);
}

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.