Consuming a public Rails API with jQuery

A previous post explained how to implement a public API in Rails. Here, we will cover how this API can be consumed with a cross-domain request using jQuery.

The idea

We’ll create a simple html file containing <ul> elements with an id. We’ll then use jQuery to fetch data (references and quantities) from the API provided by the Rails app we wrote in the previous post.

The HTML

Very basic: we’ll just have a plain HTML page (with jQuery), and add <ul> elements for products:


<ul id="1">
</ul>
<ul id="2">
</ul>

The function

We’ll need to fetch the data form the remote API using JSONP, since we’ll be doing a cross-domain request to a remote server (even though everything is local; more on that here). So we’ll write a function that will take the id of the remote object we want information for:


function fetchProductData(id){
$.ajax({
url: "http://localhost:3000/products/" + id + ".js",
dataType: "jsonp",
type: "GET",
processData: false,
contentType: "application/json",
success: function(data) {
$('#' + id).
append('<li>Remote id: ' + id + '</li>').
append('<li>Reference: ' + data['product']['reference'] + '</li>').
append('<li>Quantity: ' + data['product']['quantity'] + '</li>');
}
});
};

The setup for the function is relatively simple: pass in the API url, and some other parameters. One parameter you want to take special notice of is the “dataType: jsonp” which will make jQuery use JSONP to ensure the cross-domain request completes successfully (instead of returning an empty response). jQuery will transparently take care of specifying a callback and returning the wrapped data.

If and when the AJAX request completes successfully, we find the <ul> element to update, and add child <li> elements with the data. You’ll notice the data structure returned is pretty straightforward: the product model we defined in the previous post had a reference and a quantity, and they’re both returned in an a key-value fashion. (You can prevent the “product” root node from being included in the json data by setting ActiveRecord::Base.include_root_in_json = false in an initializer in your Rails 3 app.)

Updating every element on page load

First, we’ll define a function that will update every <ul> element on the page with a “product” class by fetching the appropriate data from the API:


function fetchData(){
$(".product").each(function(i){
fetchProductData($(this).attr("id"));
});
};

Now, we simply have to call the “fetchData” function when the page has loaded:


$(document).ready(function(){
fetchData();
});

If you now load the HTML document in a browser (while your Rails app is running), you’ll see the data being fetched from the “remote” server. Enjoy! (The full HTML file can be found here.)

This entry was posted in AJAX, jQuery. Bookmark the permalink.

4 Responses to Consuming a public Rails API with jQuery

  1. Chris says:

    In rails 3.1.1, in wrap_parameters.rb, include_root_in_json is set to false by default. This will result in “TypeError: Result of expression ‘data['product']‘ [undefined] is not an object.” because it’s deleting the root element. The choice is either to set the value to true or to change the the function from data['product']['reference'] to data['reference'].

    Thanks for the awesome post, David. You saved another brain from melting.

    Chris

  2. david says:

    Ah, I’m just starting to seriously look into the new functionality in Rails 3.1, and I haven’t had created any APIs with it yet. I personally prefer not having the root element included in the json…

    Thanks for the heads up, Chris !

  3. Usman Ahmed says:

    awesome tutorial.

    I’m trying to POST to rails API using jsonp, can you like do a little tutorial on that too?

  4. david says:

    It’s basically the same thing. But you (obviously) specify “POST” as the type. In addition, you need to add an attribute called “data”. For example: “data: {name: ‘John Doe’, age: 53},”. You can find more info about this at http://api.jquery.com/jQuery.ajax/ and http://api.jquery.com/jQuery.post/ ($.post is essentially shorthand for $.ajax with a type set to “POST”)