JavaScript
For example, I have the following JavaScript code (Dojo 1.6 is already loaded):
dojo.require("dojo.io.script")
// PART I
var jsonpArgs = {
url: "http://myapp.appspot.com/query",
content: {
id: "1234",
name: "Juan",
start_date: "2000-01-01",
callback: "recover"
}
};
// PART II
dojo.io.script.get(jsonpArgs).then(function(data) {
console.log(data);
});
// PART III
function recover(data) {
console.log(data);
}
Direct query from browser
I understand that my server will receive the query as though I typed the following into the address bar:
http://myapp.appspot.com/query?id=1234&name=Juan&start_date=2000-01-01&callback=recover
Expected response
If I directly queried my server using the browser address bar, I'll receive, in MIME type application/json
and plaintext rendered in browser, something like this:
recover(
{
id: 1234,
name: Juan,
data: [
["2000-01-01", 1234],
["2000-01-02", 5678]
]
}
);
Problem
Now, looking back at Part II of the JavaScript, I'd execute the JSONP request with dojo.io.script.get(jsonpArgs)
. This returns a Deferred
object, which I can take advantage of by chaining .then
after it. Note that I defined the handler for the .then
event to output that captured data
to the console.
However, all I get in the console is an Event
. I tried to search its data tree, but I could not find the data I expected.
Question
- Where is the response for a JSONP request stored? How do I find it?
- My server (which I control) only outputs a plaintext rendering of the data requested, wrapped in the
callback
function (here specified asrecover
), and specifies aapplication/json
MIME type. Is there anything else I need to set up on my server, so that the response data is captured by theDeferred
object?
Attempted solution
I can actually recover the response by defining the callback function (in this case recover
in Part III of the JavaScript). However, in the Dojo tutorials, they just recovered the data using the Deferred
(and .then
) framework. How do I do it using Dojo Deferred
s?
Update (using the Twitter example from Dojo tutorial)
Take for example this script from the Dojo tutorial, Getting Jiggy With JSONP. I edited it to log data to the console.
dojo.require("dojo.io.script");
dojo.io.script.get({
url: "http://search.twitter.com/search.json",
callbackParamName: "callback",
content: {q: "#dojo"}
}).then(function(data){
//we're only interested in data.results, so strip it off and return it
console.log(data); // I get an Object, not an Event, but no Twitter data when browsing the results property
console.log(data.results) // I get an array of Objects
return data.results;
});
For console.log(data)
, I get an Object
, not an Event
as illustrated by my case. Since the example implies that the data resides in data.results
, I also try to browse this tree, but I don't see my expected data from Twitter. I'm at a loss.
For console.log(data.results)
, I get an array of Object
s. If I query Twitter directly, this is what I'd get in plaintext. Each Object
contains the usual tweet meta-data like username, time, user portrait, and the tweet itself. Easy enough.
This one hits me right on the head. The handler for the .then
chain, an anonymous function, receives only one argument data
. But why is it that the results
property in console.log(data)
and the returned object I get from console.log(data.results)
are different?
I got it.
Manual callback implementation
This is the request that my server will receive:
In this case, I'll expect the following output from my server:
Three things to note:
callback
in the query URL string.callback
is implemented as a property ofjsonpArgs
.callback=recover
, my server will attachrecover(
+the_data_I_need
+)
, returns the whole string to the browser, and browser will executerecover(the_data_I_need)
. This means...function recover(one_argument_only) {doAnythingYouWantWith(one_argument_only)}
The problem with this approach is that I cannot take advantage of
Deferred
chaining using.then
. For example:This will give me an
Event
, with no trace of the expected response at all.Taking advantage of Dojo's implementation of JSONP requests
This is the request that my server will receive:
In this case, I'll expect the following output from my server:
Things to note:
Note the property of
jsonpArgs
,callbackParamName
. The value of this property must be the name of the variable (in the query URL string) expected by the server. If my server expectscallbackfoo
, thencallbackParamName: "callbackfoo"
. In my case, my server expects the namecallback
, thereforecallbackParamName: "callback"
.In the previous example, I specified in the query URL
callback=recover
and proceeded to implementfunction recover(...) {...}
. This time, I do not need to worry about it. Dojo will insert its own preferred functioncallback=some_function_name_generated_by_dojo
.I imagine
some_function_name_generated_by_dojo
to be defined as:Definition:
Of course the definition is not that simple, but the advantage of this approach is that I can take advantage of Dojo's Deferred framework. See the code below, which is identical to the previous example:
This will give me the exact data I need: