Reputation: 12279
In trying to use the stackoverflow api with ajax and jquery and I just can't get it to work. I know I have to use jsonp
as the datatype and I keep reading different ways of doing the jsonp request but I still can't get it to work.
This is my ajax request:
var API_KEY = "XXXXXXXXXXXX";
var URL = "http://api.stackoverflow.com/1.1/";
var _url = URL + 'users?filter=locrizak';
$.ajax({
dataType:'jsonp',
jsonp : false,
jsonpCallback : "onJsonp",
url: _url,
success: function(val) {
console.log('success');
//console.log(val);
},
error: function(val) {
console.log('error');
console.log(arguments);
}
});
function onJsonp() {
console.log(arguments);
};
No matter what I try I always get this response in firebug:
"parsererror" "onJsonp was not called"
I know that I am doing something really dumb because I ran into the same issues when trying to use the Twitter api but I can't for the life of me remember what I did to get it to work.
So I took a loog @genesis's working demo and tried it a few time and different ways but no luck. Then I notice my jQuery version and switched it to the one he was using and it magically worked.
I change the most recent version
http://code.jquery.com/jquery-1.6.2.min.js
to
http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js
hmm no idea why it works, possibly a bug but who knows maybe something else changed.
If anyone knows why it would be awesome if you could explain. Also I realize that jQuery adds the callback automatically but I could not get it working like that. What could I do to get this working, I guess you would say a "more proper" way?
var URL = "http://api.stackoverflow.com/1.1/";
api.get(URL + 'users?filter=locrizak');
api.get = function(url) {
$.ajax({
/*dataType:'jsonp',*/
dataType:'json',
jsonp : false,
url: url + '&jsonp=api.onJsonp',
success: function(val) {
console.log('success');
//console.log(val);
},
error: function(val) {
//error gets called but.......
console.log(arguments);
console.log('error');
console.log(val);
}
});
};
api.onJsonp = function() {
//so does the callback!!
console.log('called');
console.log(arguments);
}
//note this code is simplified
Upvotes: 4
Views: 890
Reputation: 43823
You can add jsonp:'jsonp',
to the ajax()
call. The stackoverflow API documentation states that it needs the jsonp
query paramater and the jQuery property to configure the query string parameter passed is called jsonp
. Without it, the default is to add callback=?
to the end of the URL.
I get success
in the console, running this:
var URL = "http://api.stackoverflow.com/1.1/";
var _url = URL + 'users?filter=locrizak';
$.ajax({
dataType: 'jsonp',
jsonp: 'jsonp', // <--- add this
url: _url,
success: function(val) {
console.log('success');
},
error: function(val) {
console.log('error');
console.log(arguments);
}
});
Also, jsonp:false,
should not be set to false
; it needs to be true
otherwise no query string parameter is added.
Update: Got it working correctly with jQuery v1.6.2 and using the correct parameters as described in my original answer above. The callback function must be outside the jQuery anonymous function.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>JSONP Test</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
$.ajax({
dataType:'jsonp',
jsonp: 'jsonp',
jsonpCallback: 'onJsonp',
url: 'http://api.stackoverflow.com/1.1/users?filter=locrizak',
success: function(data) {
console.log('success', data);
},
error: function(data) {
console.log('error', data);
}
});
});
function onJsonp(data) {
console.log('callback', data);
};
</script>
</head><body></body></html>
Update 2: Based on comments, here is another version, this time wrapped in an object. Note that you cannot use jsonpCallback: 'api.onJsonp',
because that is only defined inside the jQuery anonymous function. The simplest way to keep the encapsulation is to create a global function and just pass control back to the api
counterpart.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>JSONP Test</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
api = {
get: function(url) {
var URL = "http://api.stackoverflow.com/1.1/";
$.ajax({
dataType: 'jsonp',
jsonp: 'jsonp',
jsonpCallback: 'onJsonp',
url: URL + url,
success: function(data) {
console.log('success', data);
},
error: function(data) {
console.log('error', data);
}
});
},
onJsonp: function(data) {
console.log('callback', data);
}
}
api.get('users?filter=locrizak');
});
function onJsonp(data) {
api.onJsonp(data);
}
</script>
</head><body></body></html>
Upvotes: 1
Reputation: 50982
You have to call
http://api.stackoverflow.com/1.1/users?filter=locrizak&jsonp=jsonp
working demo and code:
<script>
var URL = "http://api.stackoverflow.com/1.1/";
var api;
api = {
get: function(url) {
$.ajax({
dataType: 'json',
jsonp: false,
jsonpCallback: 'api.onJsonp',
url: url + '&jsonp=api.onJsonp',
});
},
onJsonp: function(val) {
$("body").prepend(val.users[0].reputation);
console.log('called');
}
}
api.get(URL + 'users?filter=locrizak');
//note this code is simplified</script>
Upvotes: 2
Reputation: 8388
Is onJsonp defined within a closure? If so, perhaps the fact you're referring to the callback by name ('onJsonp') instead of by reference is the problem?
Two solutions: either define onJsonp in global scope, or pass it by reference by removing the quotes.
Upvotes: 1
Reputation: 11567
$.ajax({
dataType:'jsonp',
jsonp : true,
jsonpCallback : "onJsonp",
url: _url,
success: function(val) {
console.log('success');
//console.log(val);
},
error: function(val) {
console.log('error');
console.log(arguments);
}
});
set jsonp to true.
Upvotes: 0