Tuesday, December 13, 2011

A simple jQuery StackOverflow client

In the course of writing my last blog post, I decided to make a simple Stack Overflow client. Who doesn't love Stack Overflow? Here's how to do it, in case you're interested.

I've been thinking about links, as in web page links. I've also been thinking about questions. So I decided to think about what it means to link to a question.

Most links are to answers, or at least statements about the world, such as a news article, a wikipedia page, a technical explanation, or of course an update about the Russian Phobos-Grunt lunar explorer. There aren't as many links to questions, because there aren't as many webpages that are questions. Links can't tell you anything about their destination page other than what the author of the web page on which they appear chooses to reveal, and what they show in their URL structure.

Using the Stack Overflow API

So, say I'm writing a blog post and I'm talking about MVC3. I can link to a Stack Overflow question about data annotations like this:
"...So, you may ask yourself, how does data annotations really work in MVC. This is an interesting question..."
That links to a question I've favourited on Stack Overflow. But it might be nice to link to it like this:
"...So, you may ask yourself, how does data annotations really work in MVC. This is an interesting question ..."
That's because with a question, particularly a tractable one (unlike "What is the meaning of life?") like in the example, it's nice to know whether it's been answered before you click on the link. How many times as a developer have you wasted bandwidth and your patience clicking through on links thrown up by Google searches for questions that have no answer on crappy forums, spamming the answerspace. The question's meta-information, such as how much reputation the asker has and how many views its had may help you decide whether to click through to see that page.

Anyway - to the matter at hand. I thought it might be nice to show the code for embedding a question like this in a web page, because it's really quite simple, yet there are a couple of small points of interest worth paying attention to.

The HTML

To get the questions to appear in a page, I use a span or a div, with a custom data attribute supplying the question id:
"...So, you may ask yourself, <[span/div] data-question-id="5154231" class="StackOverflowQuestion">how does data annotations really work in MVC</[span/div]>? This is an interesting question...
I obviously have to go off and get the id of a question I'm interested in from the URL of that question in advance because the endpoint I'm interested in is "/questions/{id}". As a precaution against clients that don't execute Javascript, most notably Google Reader, I include the text of the question as the default inner contents of the span or div so it at least fails nicely.

Somewhere in my page I also include a reference to the Javascript file responsible for putting it all together, StackOverflow.js:
<script src='http://www.connemara.com/Scripts/Blog/StackOverflow.js' type='text/javascript'></script>
Let's look at that Javascript file now.

The JSONP

In a nutshell, all this JS file does is find any spans and divs on the page it serves that have the HTML5 custom data annotation "data-question-id" and makes a JSONP request to a Stack Exchange API endpoint with the id of the question, showing loading content until the request is succesful whereupon it formats the question metadata according to whether the original element is a span or a div.

Because I'm making an AJAX request from my site to api.stackoverflow.com, I have to use JSONP to get around the same origin policy restriction. I could use normal JSON if the endpoint I was hitting was on the same server as my calling code, but of course in this case it's not. Luckily, the Stack Exchange API supports JSONP calls, with the small stipulation that you use the "jsonp" parameter (normally, the name of this parameter is up to you). That's why you see the line: jsonp: "jsonp" in the AJAX method below.


I believe it's pretty straightforward what's happening here. But as I hinted at earlier, one of the major drawbacks of doing this sort of Javascript content insertion, especially for blog posts (which really shouldn't be surprised to find themselves in an RSS reader), is that Google Reader can't use them. Yes, it's a biggie. That's why I need to have decent default content for those spans and divs. I've written to Google to let them know their site's broken.