Tuesday, November 29, 2011

jQTouch, AJAX, Ruby on Rails

Alright, this is the beginning of my blog entries concerning software development as I get more and more passionate about it.
Today, I findings on jQTouch, AJAX, and Ruby on Rails.
jQTouch is a nice little javascript library that makes is super simple to develop webapps that look great on the iPhone. So much so that if a user adds your homepage to their homescreen, it looks so much like a native app it hurts! (well, it doesn't really, but it's quite nice).
There are other alternatives out there like iUI, jQuery Mobile and Sencha, but I decided that jQTouch was a good in-between of everything.
So the big problem I had today was that I was having a lot of issues getting the my webapp on the iPhone to make an AJAX call. When I ran the app in Chrome on several computers, there was no problem.
Quick App Summary: App built in Ruby on Rails 3, using jQTouch for the iPhone UI, and jQuery to make the AJAX calls.
I narrowed it down to it being a 406 error. Using the following code:

$.ajax({
url: '/sessions/test',
dataType: 'json',
success: function(data, textStatus, jqXHR){
alert(textStatus + ': ' + jqXHR.responseText);
},
error: function(jqXHR, textStatus, errorThrown){
alert(textStatus + ":" + errorThrown + ":" + jqXHR.status);
}
});

After that I realized my 406 error was actually stemming from how I interpreted iPhone requests.
In my Application controller, I had a bit of code that would basically look at the User Agent to determine whether or not I would use the regular Web Interface, or the Web Interface designed for the iPhone. To do this, I had a few methods like this:

def set_ios_format
if is_iphone_request? or request.format.to_sym == :iphone
request.format = if cookies["browser"] == "desktop"
then :html
else :iphone
end

# Handle AJAX Requests
if request.xhr?
request.format = :json
end
end
if is_ipad_request? or request.format.to_sym == :ipad
request.format = if cookies["browser"] == "desktop"
then :html
else :ipad
end
# Handle AJAX Requests
if request.xhr?
request.format = :json
end
end
end

You see that bit of code in there that says "Handle AJAX Requests" - this is what was missing. The problem is, when the iPhone was making an AJAX request, my Ruby on Rails code was treating that like a iPhone browser request - and setting the format to "iphone" which is an illegal format for the iPhone to accept via AJAX request.
So I do a quick check to see if the request is coming from a xhr, and if it is, set the format to "json" - could have set it to xml or whatever other AJAX response you want.
All was solved.

No comments: