locrizak
locrizak

Reputation: 12279

Trying to access stackoverflow api but getting parse error

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.

Update

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

Answers (4)

andyb
andyb

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

genesis
genesis

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

searlea
searlea

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

DrStrangeLove
DrStrangeLove

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

Related Questions