JSON and Prototype

This snippet describes how to send a JSON response from a Stripes action. Whereas the AJAX How-To article describes using Prototype's popular 'Ajax.Updater,' this uses Prototype's more granular 'Ajax.Request' in a shopping cart example.

First, add the relevant .java files. (You can also use JSON Tools, however it uses a different API to that described here.)

The action itself is similar to Calculator's:

Stripes action
public Resolution displayCart()
{
this.shoppingCart = ShoppingCartManager.getById(this.cartId);
return new StreamingResolution("text", new StringReader(this.shoppingCart.JSONCart()));
}

The only noteworthy difference is that the string it returns is a JSON object.
To see what this.shoppingCart.JSONCart() does, we peek into the DAO object:

JSONCart()
public String JSONCart()
{
// create a JSONObject to hold relevant info for each item in cart and stuff all of these objects in a JSONArray
JSONArray itemList = new JSONArray();
for (CartItem item : this.getItems()) {
JSONObject ci= new JSONObject();
ci.put("productId", item.getProduct().getId());
ci.put("name", item.getProduct().getLabel()); // product name
ci.put("price", item.getProduct().getPrice());
ci.put("quantity", item.getQuantity());
itemList.put(ci);
}

// place the array of item objects as well as other info inside another JSONObject for transport
JSONObject jsonObj = new JSONObject();
jsonObj.put("cartId", this.getId());
jsonObj.put("otherStuff", this.getStuff());
jsonObj.put("itemList", itemList);

// return the object as a JSON String
return jsonObj.toString();
}

This might generate a string like:

Sample JSON string
{"cartId": 666, "otherStuff" : "moohahaha", "itemList": [{"productId" : 42, "name" : "brimstone", "price" : $6.66, "quantity" : 2000}]}

Now some javascript to retrieve the results and do something:

sample javascript
function displayCart(ajaxResponse)
{
var JSONobj = eval('('+ ajaxResponse.responseText +')');

if (JSONobj.cartId == 666)
{
$('promotions').innerHTML = "You win a free ton of brimstone!";
}

html = "<div class='items'>";
for (var i=0; i< JSONobj.itemList.length; i++)
{
var item = JSONobj.itemList[i];
html += "<li>" + item.name + "</li">
---snip---
}

new Insertion.Bottom('cart', html);
}

The eval statement var JSONobj = eval('('+ ajaxResponse.responseText +')'); takes the returned JSON stream and converts it into a JavaScript object, which can be accessed in the rest of your script. (note: rather than eval, it might be safer to use a JavaScript JSON parser.)