I have a function which makes two rest calls to the google spreadsheetAPI. I use a $.when to make sure that the data fron thefirst call is process before dealing with the data from the second call.
The problem is that the first ajax handler(getRealNames), receives a javascript object as its argument, but the second handler(displayTeams), receives an array, the 0th element is the object I was expecting to get.
Why does one get an object and the other get an array? They are calling the same rest api. The array did not appear until I refactored the code to use deferreds instead of callback nesting. So I think this is a jquery question rather than a spreadsheetAPI question.
(see screen shot below, I've console.log'ed the arguments received by both handlers
//this is the function generating the REST requests, I just put it in for completeness
function getWorkSheet(doc_key,sheet){
return $.get('https://spreadsheets.google.com/feeds/list/'+
doc_key+'/'+sheet+
'/private/full?alt=json&access_token='
+ googleAPItoken)
.fail(function(){
alert("failed to get google doc:"+doc_key+" ,sheet: "+sheet);
});
}
function getRWMTeams() {
var nameQuery=getWorkSheet(doc_key,1);
nameQuery.done(getRealNames);
var repoQuery=getWorkSheet(doc_key,2);
//the deferred:'namesProcessed' is resolved in getRealNames
$.when(repoQuery,namesProcessed)
.done(displayTeams);
}
Thanks for asking this question, and also providing the answer. I have been having the exact same problem and trying to understand the reasoning behind "the arguments being an array" has been a challenge.
Now that I understand why the argument is array, I notice that only the first argument is an array. The second argument simply contains the data (from the resolved deferred). Do you notice this too? Here is a screenshot to explain more:
'fields' and 'defn' are my arguments in the done callback. One is an array and the other is an object. I would love to know your thoughts on this.
Eventually, more careful reading of the api doc(http://api.jquery.com/jQuery.when/) revealed the following comment in a code sample;
I had read the first comment, and assumed that the arguments were simply the return data. The second comment reveals the source of my problem.
Notwithstanding this being an old, answered question, it deserves a more complete answer before jQuery moves into its Promises/A++ era (anticipated some time in 2015).
Unlike other promise libs, jQuery promises can be resolved with multiple values. This makes life somewhat awkward for
jQuery.when()
.The documentation says :
and goes on to explain how the doneCallback arguments behave for different numbers of resolved values - and this is where it gets a bit crazy :
What you are seeing is the third case - the three values returned by
jQuery.ajax()
-data
,textStatus
andjqXHR
- bundled into an array. This is unavoidable when working with a jqXHR promise directly.However, there is a workaround. If you arrange for
getRealNames()
to include a chained.then()
, it can be made to discardtextStatus
andXHR
, and return a promise of justdata
- and hence give the single value behaviour described above. For example :That's all you need to do, but your
getRWMTeams()
function can also be tidied, as follows :or