1

I am doing a $.ajax(type: 'GET', data: ticket) where ticket is an authentication token. ticket is acquired like so:

var newTicket = $.ajax({
                type: 'POST',
                dataType: 'jsonp',
                jsonp: 'callback',
                jsonpCallback: 'JsonPCallBack',
                data: {},
                url: "https://api.examample.com?username=bar&password=foo",
        });

Once I have obtained my ticket I can do my GET:

function getData(ticket, query) {
            return $.ajax( {
                type: 'GET',
                dataType: 'jsonp',
                jsonp: 'callback',
                jsonpCallback: 'JsonPCallBack',
                data: ticket,
                url: "https://api.examample.com/?data=" + query,
            });
        } 

Putting it together:

        newTicket.done(function(ticket) {

            var ticket = ticket;
            getData(ticket, query).done(function(result) {

                console.log(result);

            }); 
        });

This works perfectly fine - my two calls are definitely working.

My challenge is that I want to make this call again for a many values of query. Here is what I tried:

// example.com promises me that I can use ticket for multiple requests
// for one ticket I will try and do multiple requests

newTicket.done(function(ticket) {

    var deferred = $.Deferred();
    var ticket = ticket;

    // Inspired by http://stackoverflow.com/questions/5627284/pass-in-an-array-of-deferreds-to-when
    requests = [];

    for (i in queries) {
        query = queries[i];
        requests.push(getData(ticket, query));
    }

    $.when.apply($, requests).done(function(result) {
        for(var i = 0; i < arguments.length; i++) {
            console.log(calculateData(arguments[i][0]));
        }
    });

});

This however does NOT work. I cannot figure out why. Any advice?

I tried adding this code:

.fail(function(jqXHR, textStatus, errorThrown) {
            console.log('jqXHR: ' + jqXHR);
            console.log('textStatus: ' + textStatus);
            console.log('errorThrown: ' + errorThrown);
        });

And this gave me:

jqXHR: [object Object]
textStatus: parsererror
errorThrown: Error: JsonPCallBack was not called

UPDATE: The simple case with only one request does not work if I do not specify jsonp and JsonPCallBack. It does work if I specify jsonp and JsonPCallBack.

I tried running the code with two requests in my array. Sniffing the packets I see that two requests are made with Status Code 200 OK. The response starts with JsonPCallBack({ and contain the correct data. So when I look at the actual repsonse everything looks correct. Why do I reach .fail()?

user1965074
  • 367
  • 5
  • 16
  • Did you try adding a `fail()` handler on that `$.when.apply`? Checking whether the `done` handler gets called? You haven't shown any evidence of attempting to troubleshoot this problem. – JLRishe Jan 19 '15 at 11:04
  • In what way it does not work? – A. Rama Jan 19 '15 at 11:19
  • @user1965074 It doesn't look like you did... – JLRishe Jan 19 '15 at 11:20
  • @user1965074 Ok, so the request is failing, apparently because the response is coming back but it's not JSONP. Have you looked at the response in your browser tools or a traffic sniffer (e.g. Fiddler) to see what the request and response look like? Is there a reason you're specifying `jsonp` and `jsonpcallback` parameters? The recommended practice is to omit them unless you specifically need them. – JLRishe Jan 19 '15 at 11:28

2 Answers2

0

The thing is that you are using a single callback for all your requests. You should remove jsonpCallback: 'JsonPCallBack' and have the server use the callback parameter like clientCallBack+"("+json+")"

Tasos Vogiatzoglou
  • 2,393
  • 12
  • 16
0

The jsonpCallback parameter indicates the name of a function name to use for wrapping the JSONP response. jQuery automatically sets up a function with this name that waits to be called so that the data returned can be handled.

You are specifying an explicit value for this parameter, which means that all of the requests will be waiting on the same function name, and all of the responses will try to call the same function name and it will be complete chaos. There will no way to route the responses correctly.

So just don't specify that parameter or the jsonp parameter. The recommended practice is to not use them unless there is a specific reason to do so.

As a side note, the code to produce your array of requests can be simplified:

var requests = $.map(queries, function (query) {
    return getData(ticket, query);
});
JLRishe
  • 99,490
  • 19
  • 131
  • 169