[erlang-questions] Best way to send JSON from erlang to the browser and back

Joe Armstrong <>
Fri Nov 25 16:02:00 CET 2011

I have the following problem:

I have  complex data structure that I want to send back and forward
between Erlang and a browser - what's the best way to do this?

This should be very simple - but the simplest solution I have found is
not entirely obvious. So I was wondering if this is the
best solution, and welcome any suggestions for improvement.

The problem is subject to the following constraints:

   1) I want the data structure to be the same after it has been on
      a "round-trip" from erlang -> browser -> erlang

   2) I want to use publicly available libraries that are in-use and

Here's the solution I use at the moment. I've chosen JSON for data
jquery in the browser, the Google chrome browser, and mochiweb.

(( is their a better choice - should I use something other than JSON for
the encoding, if so what,
Bert?, something else???)

Step 1

In the browser I request data from Erlang

I make a button in html with button id="b">click</button> and hook an event
onto it with



    function test_json(){

When I click the button a "get_term" messages is sent to an erlang mochiweb

Step 2

I make a mochiweb sevrer to reply, which looks like this:

start_server() ->
 {port, 2234}]).
loop(Req) ->
    handle(Req:get(path), Req).

handle("/get_term", Req) ->
    X = [{struct,[{string,<<"joe">>},
 <<"a string">>],
    E = mochijson2:encode(X),

The complex term is in the variable X. This is encoded with

Step 3

handle(x) is called in the browser - remember step 1? - handle is defined
like this:

function handle(x){

This prints the reply on the console and sends it back to Erlang.
To do this I call JSON.stringify(x). This seems to work correctly.

Step 4

Receive the reply in Erlang. I add an addition clause to handle/2,

handle("/echo", Req) ->
    X = json_to_erl(Req),


json_to_erl(Req) ->
    [{Str,[]}] = Req:parse_qs(),

This however is not quite right. The decoded version has changed
all the keys in the hashmap from atoms to binaries.

So when I send {struct, [{a,123}]} I get back {struct,[{<<"a">>,123}]}

This is easy to fix with:

munge({struct,L}) ->
    {struct,[{list_to_atom(binary_to_list(I)), munge(J)} || {I,J}<-L]};
munge(L) when is_list(L) ->
    [munge(I) || I <- L];
munge(X) -> X.

so  the final version is:

json_to_erl(Req) ->
    [{Str,[]}] = Req:parse_qs(),

and amazingly the round trip succeeds. Why am I amazed? - the float
got reconstructed with full precision, and the order of the keys in
the hashmap was preserved.

To summarize:

    1) mochijson2:encode(X) to term an erlang term to JSON

    2) use the jquery function ajax to receive the term
       called like this:

               success:function(x){ ...}

    3) use the jquery function ajax to send a javascript object x like this:


     4) decode the object in erlang with (assuming Str is the return value


So far my Erlang strings only contain simple english alphabetic characters,
so I don't really know what will happen if we get into utf8 encoded unicode
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20111125/b7d3a57f/attachment.html>

More information about the erlang-questions mailing list