Monday, March 12, 2007

Sending data from rails to javascript using JSON

RJS templates are a beauty, really. They allow you to run javascript code generated by rails, to be executed on the browser. Usually, this javascript code affects the DOM. But RJS, as it is often used now, is for affecting the look and behavior of a page with javascript. What if you have data that needs to be transferred from Ruby on Rails to the Javascript in the browser?

Well, my first inkling was to write a helper function that converted a matrix in Ruby, one by one, to a matrix in Javascript. But it felt ugly, like specialized complexity that's just in your face. There has to be a better way, since I can't be the first one to run into this problem.

Of course, there is and that's using JSON--JavaScript Object Notation. A simple way to think of it is as XML, with less overhead, because JSON is simply that, a way to represent data in a standard format that's easy for both humans to read and machines to parse.

In Rails 1.1+ (apparently, this has been around since at least May 2006), there's been an extension added to Object class, and that's to_json(). That's right. You can serialize any object in rails to JSON, simply by calling to_json(). However, it's not documented in the Rails API, so your best bet is to google for it.

As a quick and dirty way to demonstrate it, you can have this in your controller:

def some_action
# some type of data from somewhere in the database
@data = Data.find(1)
end

and then the following in your view somewhere:

<script type="text/javascript">
var data = <%= @data.to_json %>
// act on data as if it were a Javascript object
</script>

You should be able to create helper functions that generate the javascript tags and the enclosing javascript so that it'd be a bit prettier, so it'd look like this in your view instead:

<%= act_on_data(@data) %>

Neat. So in this way, you can pass your data from your server to code in your views that isn't to be displayed in HTML, but in some other form. One person has tied Adobe's Flex in with Rails for this very purpose. Tip!

But one other thing that I realized after reading through JSON for the masses, is somewhat startling...at least to me. And in hindsight, perhaps it was because it never seemed easy to do in XML.

Usually data transfer languages such as XML and the like are declarative languages. They say the "what" instead of the "how". That hasn't stopped people from trying to do remote procedure calls with XML-RPC. But with JSON, it really is an object notation, meaning that you can put functions as data. So the example I gave before of javascript classes, they can instead be written in JSON notion in the source code and it would still work.

Therefore, the javascript interpreter itself IS the parser for JSON. You don't need a separate parser in javascript like you do in XML. If JSON really does have cross-language compatibility, that's actually rather neat. This implies that JSON-RPC is possible, and of course, a quick search on Google reveals that this is exactly what people are trying.

This kind of reminds me of how Von Neumann's computer architecture was novel at the time because it treated program commands and data as the same thing. Before, computers had one place for data, and one place for a program. You didn't store programs the same place that you stored data. By the same token, it also reminds me of how Lisp's data is pretty much its code, and vice versa, and that's where it derives a lot of its power.

Looking into the future (meaning, here on out, I'm talking out of my ass), perhaps that makes it easier to do distributed computing, and the stitching together of applications so very much desired by the Service Orientated Architecture crowd, but also a host of security issues. You might be able to get javascript programs that update each other on the fly in the field, instead of going all the way back to the server for updates (maybe).

No comments:

Post a Comment